├── .gitattributes ├── .gitignore ├── NOTICE.txt ├── app ├── .gitignore ├── build.gradle ├── doclib │ ├── 0001-Xposed-Only-generate-docs-stubs-API-file-for-include.patch │ ├── 0002-Xposed-Properly-hide-overridden-methods.patch │ ├── 0003-Xposed-Ignore-missing-documentation-for-deprecated-c.patch │ ├── 0004-Xposed-Improve-label-for-see-link-tags.patch │ ├── api │ │ ├── android_23.txt │ │ ├── changelog.txt │ │ ├── current.txt │ │ ├── xposed_000.txt │ │ ├── xposed_036.txt │ │ ├── xposed_037.txt │ │ ├── xposed_039.txt │ │ ├── xposed_042.txt │ │ ├── xposed_050.txt │ │ ├── xposed_051.txt │ │ ├── xposed_052.txt │ │ ├── xposed_053.txt │ │ ├── xposed_060.txt │ │ ├── xposed_063.txt │ │ ├── xposed_065.txt │ │ ├── xposed_081.txt │ │ └── xposed_082.txt │ ├── doclava.jar │ ├── jsilver.jar │ ├── overview.html │ └── template │ │ ├── assets │ │ ├── GPL-LICENSE.txt │ │ ├── LICENSE.txt │ │ ├── css │ │ │ ├── default.css │ │ │ └── fullscreen.css │ │ ├── images │ │ │ ├── arrows-up-down.png │ │ │ ├── favicon.ico │ │ │ ├── fullscreen.png │ │ │ ├── resizable-s2.png │ │ │ ├── sprite-2x.png │ │ │ ├── sprite.png │ │ │ ├── triangle-closed-small.png │ │ │ ├── triangle-closed.png │ │ │ ├── triangle-opened-small.png │ │ │ ├── triangle-opened.png │ │ │ ├── xposed_logo.png │ │ │ └── xposed_logo@2x.png │ │ └── js │ │ │ ├── android_3p-bundle.js │ │ │ ├── docs.js │ │ │ └── prettify.js │ │ ├── class.cs │ │ ├── classes.cs │ │ ├── components │ │ └── masthead.cs │ │ ├── customizations.cs │ │ ├── data.hdf │ │ ├── footer.cs │ │ ├── head_tag.cs │ │ ├── header.cs │ │ ├── hierarchy.cs │ │ ├── index.cs │ │ ├── jd_lists_unified.cs │ │ ├── macros_override.cs │ │ ├── navtree_data.cs │ │ ├── nosidenavpage.cs │ │ ├── package.cs │ │ ├── packages.cs │ │ ├── timestamp.cs │ │ ├── todo.cs │ │ └── trailer.cs ├── lint.xml └── src │ └── main │ ├── AndroidManifest.xml │ ├── apacheCommonsLang │ ├── LICENSE.txt │ ├── MODIFICATIONS.txt │ ├── NOTICE.txt │ ├── RELEASE-NOTES.txt │ └── external │ │ └── org │ │ └── apache │ │ └── commons │ │ └── lang3 │ │ ├── ArrayUtils.java │ │ ├── CharSequenceUtils.java │ │ ├── CharUtils.java │ │ ├── ClassUtils.java │ │ ├── JavaVersion.java │ │ ├── ObjectUtils.java │ │ ├── StringUtils.java │ │ ├── SystemUtils.java │ │ ├── Validate.java │ │ ├── builder │ │ ├── Builder.java │ │ ├── CompareToBuilder.java │ │ ├── EqualsBuilder.java │ │ ├── HashCodeBuilder.java │ │ ├── IDKey.java │ │ ├── ReflectionToStringBuilder.java │ │ ├── ToStringBuilder.java │ │ ├── ToStringStyle.java │ │ └── package.html │ │ ├── exception │ │ ├── CloneFailedException.java │ │ └── package.html │ │ ├── mutable │ │ ├── Mutable.java │ │ ├── MutableInt.java │ │ └── package.html │ │ ├── overview.html │ │ ├── package.html │ │ ├── reflect │ │ ├── MemberUtils.java │ │ ├── MethodUtils.java │ │ └── package.html │ │ └── tuple │ │ ├── ImmutablePair.java │ │ ├── Pair.java │ │ └── package.html │ └── java │ ├── android │ ├── app │ │ ├── AndroidAppHelper.java │ │ └── package-info.java │ └── content │ │ └── res │ │ ├── XModuleResources.java │ │ ├── XResForwarder.java │ │ ├── XResources.java │ │ └── package-info.java │ └── de │ └── robv │ └── android │ └── xposed │ ├── DexCreator.java │ ├── IXposedHookCmdInit.java │ ├── IXposedHookInitPackageResources.java │ ├── IXposedHookLoadPackage.java │ ├── IXposedHookZygoteInit.java │ ├── IXposedMod.java │ ├── SELinuxHelper.java │ ├── XC_MethodHook.java │ ├── XC_MethodReplacement.java │ ├── XSharedPreferences.java │ ├── XposedBridge.java │ ├── XposedHelpers.java │ ├── XposedInit.java │ ├── callbacks │ ├── IXUnhook.java │ ├── XC_InitPackageResources.java │ ├── XC_LayoutInflated.java │ ├── XC_LoadPackage.java │ ├── XCallback.java │ └── package-info.java │ ├── package-info.java │ └── services │ ├── BaseService.java │ ├── BinderService.java │ ├── DirectAccessService.java │ ├── FileResult.java │ ├── ZygoteService.java │ └── package-info.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── hiddenapistubs ├── .gitignore ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ ├── android │ ├── app │ │ ├── ActivityThread.java │ │ └── LoadedApk.java │ ├── content │ │ ├── pm │ │ │ └── PackageParser.java │ │ └── res │ │ │ ├── AssetManager.java │ │ │ ├── CompatibilityInfo.java │ │ │ ├── Resources.java │ │ │ └── TypedArray.java │ └── os │ │ ├── SELinux.java │ │ └── ServiceManager.java │ ├── com │ └── android │ │ └── internal │ │ ├── os │ │ ├── RuntimeInit.java │ │ └── ZygoteInit.java │ │ └── util │ │ └── XmlUtils.java │ └── xposed │ └── dummy │ ├── XResourcesSuperClass.java │ └── XTypedArraySuperClass.java └── settings.gradle /.gitattributes: -------------------------------------------------------------------------------- 1 | *.bat text eol=crlf 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .idea 3 | .gradle 4 | /local.properties 5 | /.idea/workspace.xml 6 | /.idea/libraries 7 | .DS_Store 8 | /build 9 | /captures 10 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | LICENSE FOR THE MAIN PRODUCT 2 | ============================ 3 | 4 | Copyright 2013 rovo89, Tungstwenty 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License. 17 | 18 | 19 | 20 | INCLUDED LIBRARIES 21 | ================== 22 | 23 | This product includes slightly modified code of the "Apache Commons Lang" 24 | library. See lib/apache-commons-lang for details. 25 | Here is a copy of the NOTICE.txt from that directory: 26 | ------------------------------------------------------------------------- 27 | Apache Commons Lang 28 | Copyright 2001-2011 The Apache Software Foundation 29 | 30 | This product includes software developed by 31 | The Apache Software Foundation (http://www.apache.org/). 32 | 33 | This product includes software from the Spring Framework, 34 | under the Apache License 2.0 (see: StringUtils.containsWhitespace()) 35 | ------------------------------------------------------------------------- 36 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | import com.android.builder.core.BuilderConstants 2 | 3 | apply plugin: 'com.android.application' 4 | 5 | android { 6 | compileSdkVersion 23 7 | buildToolsVersion "23.0.3" 8 | 9 | defaultConfig { 10 | minSdkVersion 15 11 | } 12 | 13 | sourceSets { 14 | main { 15 | java.srcDirs += ['src/main/apacheCommonsLang'] 16 | } 17 | } 18 | 19 | // Only build the release variant 20 | variantFilter { variant -> 21 | if (variant.buildType.name != BuilderConstants.RELEASE) { 22 | variant.ignore = true 23 | } 24 | } 25 | 26 | // Add the hidden API stub classes to the bootclasspath. 27 | // As they have to be injected before the official SDK classes and must not be part of the 28 | // final JAR/APK, the best way seems to compile them in a separate project and use some dirty 29 | // magic to add its output directory to all variants' configuration. 30 | def hiddenapi = project(':hiddenapistubs') 31 | hiddenapi.afterEvaluate { 32 | hiddenapi.android.compileSdkVersion compileSdkVersion 33 | hiddenapi.android.buildToolsVersion buildToolsVersion 34 | preBuild.dependsOn ':hiddenapistubs:assembleRelease' 35 | hiddenapi.preBuild << { 36 | def hiddenapiCompiler = hiddenapi.android.libraryVariants[0].javaCompiler 37 | def hiddenapiDestPath = hiddenapiCompiler.destinationDir.getAbsolutePath() 38 | applicationVariants.all { variant -> 39 | variant.javaCompiler.with { 40 | dependsOn hiddenapiCompiler 41 | options.bootClasspath = hiddenapiDestPath + File.pathSeparator + options.bootClasspath 42 | if (variant.name == BuilderConstants.RELEASE) { 43 | generateDocs.options.bootClasspath = files(options.bootClasspath.split(File.pathSeparator), destinationDir).asType(List) 44 | generateStubs.options.bootClasspath = generateDocs.options.bootClasspath 45 | compileStubs.classpath = files(options.bootClasspath.split(File.pathSeparator)) 46 | } 47 | } 48 | } 49 | } 50 | } 51 | } 52 | 53 | task generateDocs(type: Javadoc, dependsOn: 'compileReleaseSources') { 54 | source = file('src/main/java') 55 | ext.templateDir = file('doclib/template') 56 | ext.overviewFile = file('doclib/overview.html') 57 | inputs.dir ext.templateDir 58 | inputs.file ext.overviewFile 59 | title = null 60 | 61 | options { 62 | doclet = 'com.google.doclava.Doclava' 63 | docletpath = fileTree(dir: 'doclib', include: '**/*.jar').asType(List) 64 | jFlags '-Dignore.symbol.file' 65 | addFileOption 'templatedir', ext.templateDir 66 | addFileOption 'overview', ext.overviewFile 67 | addBooleanOption 'nodefaultassets', true 68 | addStringOption 'hdf android.whichdoc', 'offline' 69 | addStringOption 'federate android', 'http://developer.android.com' 70 | addFileOption 'federationapi android', fileTree(dir: 'doclib/api', include: 'android_*.txt').singleFile 71 | addFileOption 'proofread', file("$buildDir/docs/proofread.txt") 72 | addStringOption 'todo', 'reference/todo.html' 73 | fileTree(dir: 'doclib/api', include: 'xposed_*.txt').visit { 74 | addStringOption 'since ' + it.file, it.name.replaceFirst(/^xposed_0*(\d*)\.txt$/, '$1') 75 | } 76 | 77 | // The sources of the Android SDK are added to the sourcepath. 78 | // This ensures that Javadoc can be inherited properly, but it 79 | // takes longer and throws a lot of errors (which we ignore here). 80 | def sdkSources = file("$android.sdkDirectory/sources/$android.compileSdkVersion") 81 | assert sdkSources.exists() 82 | addFileOption 'sourcepath', sdkSources 83 | 84 | failOnError = false 85 | addStringOption 'Xmaxwarns', '1' 86 | addStringOption 'Xmaxerrs', '1' 87 | (101..122).each { 88 | addBooleanOption 'hide ' + it, true 89 | } 90 | addBooleanOption 'hidePackage xposed.dummy', true 91 | } 92 | } 93 | 94 | task generateStubs(type: Javadoc, dependsOn: 'compileReleaseSources') { 95 | source = file('src/main/java') 96 | ext.stubsDir = "$buildDir/api/stub-sources" 97 | outputs.dir ext.stubsDir 98 | title = null 99 | 100 | options { 101 | doclet = 'com.google.doclava.Doclava' 102 | docletpath = fileTree(dir: 'doclib', include: '**/*.jar').asType(List) 103 | jFlags '-Dignore.symbol.file' 104 | addBooleanOption 'nodocs', true 105 | addFileOption 'stubs', file(ext.stubsDir) 106 | addFileOption 'api', file('doclib/api/current.txt') 107 | addBooleanOption 'hide 111', true 108 | addBooleanOption 'hide 113', true 109 | addBooleanOption 'hidePackage xposed.dummy', true 110 | } 111 | } 112 | 113 | task compileStubs(type: JavaCompile, dependsOn: 'generateStubs') { 114 | source = fileTree(generateStubs.ext.stubsDir) 115 | destinationDir = file("$buildDir/api/stub-classes") 116 | options.compilerArgs += '-XDsuppressNotes' 117 | } 118 | 119 | task jarStubs(type: Jar) { 120 | from compileStubs 121 | destinationDir = file("$buildDir/api") 122 | baseName = 'api' 123 | } 124 | 125 | task jarStubsSource(type: Jar) { 126 | from generateStubs.source 127 | destinationDir = jarStubs.destinationDir 128 | baseName = jarStubs.baseName 129 | classifier = 'sources' 130 | } 131 | 132 | task generateAPI(dependsOn: ['generateDocs', 'generateStubs', 'jarStubs', 'jarStubsSource']) 133 | 134 | // Make sure that hiddenapistubs are placed before the Android SDK in app.iml 135 | // as there doesn't seem to be any way to configure this in Android Studio. 136 | task fixIml { 137 | ext.imlFile = projectDir.absolutePath + '/' + project.name + '.iml' 138 | inputs.file imlFile 139 | outputs.file imlFile 140 | 141 | doLast { 142 | if (!file(imlFile).exists()) 143 | return 144 | 145 | // Parse the existing iml file 146 | def parse = new XmlParser().parse(imlFile) 147 | def moduleComponent = parse.component.find { it.@name == 'NewModuleRootManager' } 148 | 149 | // Check if it has already been fixed 150 | def orderEntries = moduleComponent.orderEntry 151 | if (orderEntries.find { it.@type == 'module' && it.@'module-name' == 'hiddenapistubs' }) 152 | return 153 | 154 | // Determine the index of the Android SDK entry 155 | def jdkOrderEntry = orderEntries.find { it.@type == 'jdk' } 156 | def jdkOrderEntryIndex = moduleComponent.children().indexOf(jdkOrderEntry) 157 | 158 | // Add the new entry just before it 159 | moduleComponent.children().add(jdkOrderEntryIndex, new Node(null, 'orderEntry', 160 | ['type': 'module', 'module-name': 'hiddenapistubs', 'exported': ''])) 161 | 162 | // Write the fixed iml file 163 | def printer = new XmlNodePrinter(new PrintWriter(new FileWriter(imlFile))) 164 | printer.preserveWhitespace = true 165 | printer.print(parse) 166 | } 167 | } 168 | 169 | tasks.preBuild.dependsOn fixIml 170 | -------------------------------------------------------------------------------- /app/doclib/0001-Xposed-Only-generate-docs-stubs-API-file-for-include.patch: -------------------------------------------------------------------------------- 1 | From fd3b7d73abeb44dc75bdea49709a8014b740376a Mon Sep 17 00:00:00 2001 2 | From: rovo89 3 | Date: Wed, 24 Feb 2016 20:09:55 +0100 4 | Subject: [PATCH 1/4] [Xposed] Only generate docs/stubs/API file for included 5 | classes 6 | 7 | XposedBridge puts some classes into existing android.* packages. 8 | However, Doclava can only consider/ignore all classes in a package. 9 | These changes make sure that only the explicitly specified classes are 10 | considered. 11 | 12 | Change-Id: I3f0f9d20da15d6057816372e39bdeb0887c8c5a8 13 | --- 14 | src/com/google/doclava/Doclava.java | 8 ++++---- 15 | src/com/google/doclava/NavTree.java | 2 +- 16 | src/com/google/doclava/PackageInfo.java | 2 +- 17 | src/com/google/doclava/Stubs.java | 6 +++--- 18 | 4 files changed, 9 insertions(+), 9 deletions(-) 19 | 20 | diff --git a/src/com/google/doclava/Doclava.java b/src/com/google/doclava/Doclava.java 21 | index 23ede5f..10c6d2e 100644 22 | --- a/src/com/google/doclava/Doclava.java 23 | +++ b/src/com/google/doclava/Doclava.java 24 | @@ -873,7 +873,7 @@ public class Doclava { 25 | 26 | SortedMap sorted = new TreeMap(); 27 | for (ClassInfo cl : classes) { 28 | - if (cl.isHiddenOrRemoved()) { 29 | + if (cl.isHiddenOrRemoved() || !cl.isIncluded()) { 30 | continue; 31 | } 32 | sorted.put(cl.qualifiedName(), cl); 33 | @@ -1283,7 +1283,7 @@ public class Doclava { 34 | ClassInfo[] classes = Converter.rootClasses(); 35 | ArrayList info = new ArrayList(); 36 | for (ClassInfo cl : classes) { 37 | - if (!cl.isHiddenOrRemoved()) { 38 | + if (!cl.isHiddenOrRemoved() && cl.isIncluded()) { 39 | info.add(cl); 40 | } 41 | } 42 | @@ -1298,7 +1298,7 @@ public class Doclava { 43 | 44 | for (ClassInfo cl : classes) { 45 | Data data = makePackageHDF(); 46 | - if (!cl.isHiddenOrRemoved()) { 47 | + if (!cl.isHiddenOrRemoved() && cl.isIncluded()) { 48 | writeClass(cl, data); 49 | } 50 | } 51 | @@ -1315,7 +1315,7 @@ public class Doclava { 52 | public static void makeClassListHDF(Data data, String base, ClassInfo[] classes) { 53 | for (int i = 0; i < classes.length; i++) { 54 | ClassInfo cl = classes[i]; 55 | - if (!cl.isHiddenOrRemoved()) { 56 | + if (!cl.isHiddenOrRemoved() && cl.isIncluded()) { 57 | cl.makeShortDescrHDF(data, base + "." + i); 58 | } 59 | } 60 | diff --git a/src/com/google/doclava/NavTree.java b/src/com/google/doclava/NavTree.java 61 | index cbe9fee..4ce7438 100644 62 | --- a/src/com/google/doclava/NavTree.java 63 | +++ b/src/com/google/doclava/NavTree.java 64 | @@ -147,7 +147,7 @@ public class NavTree { 65 | List children = new ArrayList(); 66 | 67 | for (ClassInfo cl : classes) { 68 | - if (cl.checkLevel()) { 69 | + if (cl.checkLevel() && cl.isIncluded()) { 70 | children.add(new Node(cl.name(), cl.htmlPage(), null, cl.getSince())); 71 | } 72 | } 73 | diff --git a/src/com/google/doclava/PackageInfo.java b/src/com/google/doclava/PackageInfo.java 74 | index 46b5b8f..89d2d36 100644 75 | --- a/src/com/google/doclava/PackageInfo.java 76 | +++ b/src/com/google/doclava/PackageInfo.java 77 | @@ -190,7 +190,7 @@ public class PackageInfo extends DocInfo implements ContainerInfo { 78 | ArrayList out = new ArrayList(); 79 | 80 | for (ClassInfo cl : classes) { 81 | - if (!cl.isHiddenOrRemoved()) { 82 | + if (!cl.isHiddenOrRemoved() && cl.isIncluded()) { 83 | out.add(cl); 84 | } 85 | } 86 | diff --git a/src/com/google/doclava/Stubs.java b/src/com/google/doclava/Stubs.java 87 | index 6795bd4..b088e40 100644 88 | --- a/src/com/google/doclava/Stubs.java 89 | +++ b/src/com/google/doclava/Stubs.java 90 | @@ -91,7 +91,7 @@ public class Stubs { 91 | // complain about anything that looks includeable but is not supposed to 92 | // be written, e.g. hidden things 93 | for (ClassInfo cl : notStrippable) { 94 | - if (!cl.isHiddenOrRemoved()) { 95 | + if (!cl.isHiddenOrRemoved() && cl.isIncluded()) { 96 | for (MethodInfo m : cl.selfMethods()) { 97 | if (m.isHiddenOrRemoved()) { 98 | Errors.error(Errors.UNAVAILABLE_SYMBOL, m.position(), "Reference to unavailable method " 99 | @@ -172,7 +172,7 @@ public class Stubs { 100 | HashMap> packages = new HashMap>(); 101 | final HashSet stubPackageWildcards = extractWildcards(stubPackages); 102 | for (ClassInfo cl : notStrippable) { 103 | - if (!cl.isDocOnly()) { 104 | + if (!cl.isDocOnly() && cl.isIncluded()) { 105 | if (shouldWriteStub(cl.containingPackage().name(), stubPackages, stubPackageWildcards)) { 106 | // write out the stubs 107 | if (stubsDir != null) { 108 | @@ -1182,7 +1182,7 @@ public class Stubs { 109 | Collections.sort(classes, ClassInfo.comparator); 110 | boolean hasWrittenPackageHead = false; 111 | for (ClassInfo cl : classes) { 112 | - if (cl.hasRemovedSelfMembers()) { 113 | + if (cl.hasRemovedSelfMembers() && cl.isIncluded()) { 114 | if (!hasWrittenPackageHead) { 115 | hasWrittenPackageHead = true; 116 | apiWriter.print("package "); 117 | -- 118 | 2.7.0 119 | 120 | -------------------------------------------------------------------------------- /app/doclib/0002-Xposed-Properly-hide-overridden-methods.patch: -------------------------------------------------------------------------------- 1 | From 39f47d43639308568aa6f4b485d1e5f47020965a Mon Sep 17 00:00:00 2001 2 | From: rovo89 3 | Date: Wed, 24 Feb 2016 20:14:49 +0100 4 | Subject: [PATCH 2/4] [Xposed] Properly hide overridden methods 5 | 6 | It shouldn't matter whether the method has any tags. 7 | 8 | Change-Id: I205941be9a822258ae9619ac18cebbe9f9471de2 9 | --- 10 | src/com/google/doclava/MethodInfo.java | 4 +--- 11 | 1 file changed, 1 insertion(+), 3 deletions(-) 12 | 13 | diff --git a/src/com/google/doclava/MethodInfo.java b/src/com/google/doclava/MethodInfo.java 14 | index 993c3c9..2d824ea 100644 15 | --- a/src/com/google/doclava/MethodInfo.java 16 | +++ b/src/com/google/doclava/MethodInfo.java 17 | @@ -107,7 +107,6 @@ public class MethodInfo extends MemberInfo implements AbstractMethodInfo, Resolv 18 | for (ClassInfo iface : queue) { 19 | for (MethodInfo me : iface.methods()) { 20 | if (me.name().equals(name) && me.signature().equals(signature) 21 | - && me.inlineTags().tags() != null && me.inlineTags().tags().length > 0 22 | && notStrippable.contains(me.containingClass())) { 23 | return me; 24 | } 25 | @@ -165,8 +164,7 @@ public class MethodInfo extends MemberInfo implements AbstractMethodInfo, Resolv 26 | addInterfaces(containingClass().realInterfaces(), queue); 27 | for (ClassInfo iface : queue) { 28 | for (MethodInfo me : iface.methods()) { 29 | - if (me.name().equals(name) && me.signature().equals(signature) 30 | - && me.inlineTags().tags() != null && me.inlineTags().tags().length > 0) { 31 | + if (me.name().equals(name) && me.signature().equals(signature)) { 32 | return iface; 33 | } 34 | } 35 | -- 36 | 2.7.0 37 | 38 | -------------------------------------------------------------------------------- /app/doclib/0003-Xposed-Ignore-missing-documentation-for-deprecated-c.patch: -------------------------------------------------------------------------------- 1 | From 38bb62c9fc590f17e2aac0e38ad3fb2448b1135a Mon Sep 17 00:00:00 2001 2 | From: rovo89 3 | Date: Wed, 24 Feb 2016 20:19:09 +0100 4 | Subject: [PATCH 3/4] [Xposed] Ignore missing documentation for deprecated 5 | classes/methods 6 | 7 | The deprecation comment should be enough. 8 | 9 | Change-Id: I399ce5071d2c506e98621fdefb8f74102829948d 10 | --- 11 | src/com/google/doclava/TodoFile.java | 12 ++++++------ 12 | 1 file changed, 6 insertions(+), 6 deletions(-) 13 | 14 | diff --git a/src/com/google/doclava/TodoFile.java b/src/com/google/doclava/TodoFile.java 15 | index 36df2c7..efbd1b0 100644 16 | --- a/src/com/google/doclava/TodoFile.java 17 | +++ b/src/com/google/doclava/TodoFile.java 18 | @@ -84,7 +84,7 @@ public class TodoFile { 19 | int errors = 0; 20 | int total = 1; 21 | 22 | - if (!areTagsUseful(cl.inlineTags())) { 23 | + if (!cl.comment().isDeprecated() && !areTagsUseful(cl.inlineTags())) { 24 | setHDF(data, base + errors, cl.position(), "<class comment>", MISSING); 25 | errors++; 26 | } 27 | @@ -93,7 +93,7 @@ public class TodoFile { 28 | for (MethodInfo m : cl.constructors()) { 29 | boolean good = true; 30 | total++; 31 | - if (m.checkLevel()) { 32 | + if (m.checkLevel() && !m.comment().isDeprecated()) { 33 | if (!areTagsUseful(m.inlineTags())) { 34 | setHDF(data, base + errors, m.position(), m.prettySignature(), MISSING); 35 | good = false; 36 | @@ -107,9 +107,9 @@ public class TodoFile { 37 | for (MethodInfo m : cl.selfMethods()) { 38 | boolean good = true; 39 | total++; 40 | - if (m.checkLevel()) { 41 | + if (m.checkLevel() && !m.comment().isDeprecated()) { 42 | if (!areTagsUseful(m.inlineTags())) { 43 | - setHDF(data, base + errors, m.position(), m.name() + m.prettySignature(), MISSING); 44 | + setHDF(data, base + errors, m.position(), m.prettySignature(), MISSING); 45 | good = false; 46 | } 47 | } 48 | @@ -122,7 +122,7 @@ public class TodoFile { 49 | for (FieldInfo f : cl.enumConstants()) { 50 | boolean good = true; 51 | total++; 52 | - if (f.checkLevel()) { 53 | + if (f.checkLevel() && !f.comment().isDeprecated()) { 54 | if (!areTagsUseful(f.inlineTags())) { 55 | setHDF(data, base + errors, f.position(), f.name(), MISSING); 56 | good = false; 57 | @@ -136,7 +136,7 @@ public class TodoFile { 58 | for (FieldInfo f : cl.selfFields()) { 59 | boolean good = true; 60 | total++; 61 | - if (f.checkLevel()) { 62 | + if (f.checkLevel() && !f.comment().isDeprecated()) { 63 | if (!areTagsUseful(f.inlineTags())) { 64 | setHDF(data, base + errors, f.position(), f.name(), MISSING); 65 | good = false; 66 | -- 67 | 2.7.0 68 | 69 | -------------------------------------------------------------------------------- /app/doclib/0004-Xposed-Improve-label-for-see-link-tags.patch: -------------------------------------------------------------------------------- 1 | From 094aced02587a659036d2d83296cfed49d5e3ef8 Mon Sep 17 00:00:00 2001 2 | From: rovo89 3 | Date: Wed, 24 Feb 2016 20:55:37 +0100 4 | Subject: [PATCH 4/4] [Xposed] Improve label for see/link tags 5 | 6 | For methods/fields in other classes, mention the class name. 7 | For varargs methods, add ... notation. 8 | 9 | Change-Id: Ic16193662c618e697583d4fa0bdf6eae77e3903e 10 | --- 11 | src/com/google/doclava/LinkReference.java | 11 ++++++++++- 12 | 1 file changed, 10 insertions(+), 1 deletion(-) 13 | 14 | diff --git a/src/com/google/doclava/LinkReference.java b/src/com/google/doclava/LinkReference.java 15 | index 816bdb1..e31c145 100644 16 | --- a/src/com/google/doclava/LinkReference.java 17 | +++ b/src/com/google/doclava/LinkReference.java 18 | @@ -303,9 +303,15 @@ public class LinkReference { 19 | result.memberInfo = method; 20 | } 21 | } 22 | + if (result.classInfo != cl) { 23 | + result.referencedMemberName = result.classInfo.name() + "." + mem; 24 | + } 25 | + } 26 | + 27 | + if (result.referencedMemberName == null) { 28 | + result.referencedMemberName = mem; 29 | } 30 | 31 | - result.referencedMemberName = mem; 32 | if (params != null) { 33 | result.referencedMemberName = result.referencedMemberName + '('; 34 | len = params.length; 35 | @@ -317,6 +323,9 @@ public class LinkReference { 36 | } 37 | result.referencedMemberName = 38 | result.referencedMemberName + params[len] + paramDimensions[len]; 39 | + if (varargs) { 40 | + result.referencedMemberName = result.referencedMemberName + "..."; 41 | + } 42 | } 43 | result.referencedMemberName = result.referencedMemberName + ")"; 44 | } 45 | -- 46 | 2.7.0 47 | 48 | -------------------------------------------------------------------------------- /app/doclib/api/changelog.txt: -------------------------------------------------------------------------------- 1 | This file lists the changes in the Xposed Framework API: 2 | -------------------------------------------------------- 3 | v82: 4 | added XposedHelpers.findClassIfExists() helper 5 | added XposedHelpers.findMethodIfExists() helpers 6 | added XposedHelpers.findConstructorIfExists() helpers 7 | added XposedHelpers.findFieldIfExists() helper 8 | 9 | v81: 10 | added IXUnhook.getCallback() 11 | deprecated XposedBridge.unhookMethod(), use IXUnhook instead 12 | deprecated full-name variants of XResources.hookLayout() etc. 13 | removed several other unhooking methods, use IXUnhook instead 14 | removed XC_LoadPackage / XC_InitPackageResources constructors 15 | removed class de.robv.android.xposed.IXposedHookCmdInit 16 | 17 | v65: 18 | added XposedBridge.getXposedVersion() 19 | deprecated XposedBridge.XPOSED_BRIDGE_VERSION 20 | 21 | v63: 22 | added XposedHelpers.incrementMethodDepth() 23 | added XposedHelpers.decrementMethodDepth() 24 | added XposedHelpers.getMethodDepth() 25 | 26 | v60: 27 | added IXposedHookZygoteInit.StartupParam.startsSystemServer 28 | added class de.robv.android.xposed.SELinuxHelper 29 | added class de.robv.android.xposed.services.BaseService 30 | added class de.robv.android.xposed.services.FileResult 31 | 32 | v53: 33 | added XSharedPreferences.getFile() 34 | added XSharedPreferences.hasFileChanged() 35 | 36 | v52: 37 | added XResources.getPackageNameDuringConstruction() 38 | 39 | v51: 40 | deprecated class de.robv.android.xposed.IXposedHookCmdInit (removed in v81) 41 | added XposedHelpers.findAndHookConstructor() 42 | added XposedHelpers.findConstructorExact() variants 43 | 44 | v50: 45 | added class android.content.res.XResources.DimensionReplacement 46 | 47 | v42: 48 | added XposedHelpers.findFirstFieldByExactType() 49 | 50 | v39: 51 | added XCallback.Param.getExtra() 52 | 53 | v37: 54 | added XposedBridge.XPOSED_BRIDGE_VERSION (deprecated again in v65) 55 | 56 | v36: 57 | added XposedHelpers.findMethodsByExactParameters() 58 | -------------------------------------------------------------------------------- /app/doclib/doclava.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rovo89/XposedBridge/a535c02ed9dfd53683cc0274d9f95bcb6ffb9f79/app/doclib/doclava.jar -------------------------------------------------------------------------------- /app/doclib/jsilver.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rovo89/XposedBridge/a535c02ed9dfd53683cc0274d9f95bcb6ffb9f79/app/doclib/jsilver.jar -------------------------------------------------------------------------------- /app/doclib/overview.html: -------------------------------------------------------------------------------- 1 | 2 | Welcome to the Javadoc reference of the Xposed Framework API. It's meant for module developers who want to understand which classes and methods they can use. The most ones are: 3 | 4 |
    5 |
  • {@link de.robv.android.xposed.IXposedHookZygoteInit}
  • 6 |
  • {@link de.robv.android.xposed.IXposedHookLoadPackage}
  • 7 |
  • {@link de.robv.android.xposed.XposedHelpers#findAndHookMethod(String, ClassLoader, String, Object...) XposedHelpers.findAndHookMethod()}
  • 8 |
  • {@link de.robv.android.xposed.IXposedHookInitPackageResources}
  • 9 |
  • {@link android.content.res.XResources#setReplacement(String, String, String, Object) XResources.setReplacement()} 10 |
11 | 12 | If you're completely new to writing modules, you should read the tutorial first. 13 | In case of questions, someone on XDA can probably help you (if you describe exactly what you're trying to do and what you've already tried). 14 | 15 | -------------------------------------------------------------------------------- /app/doclib/template/assets/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 John Resig, http://jquery.com/ 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /app/doclib/template/assets/css/fullscreen.css: -------------------------------------------------------------------------------- 1 | 2 | /* ============================================================================= 3 | Columns 4 | ========================================================================== */ 5 | /* Applied to body to debug layout alignments 6 | .grid { 7 | width:100%; 8 | height:100%; 9 | background:url(../images/grid.png) center repeat-y; 10 | top:0px; 11 | margin:auto; 12 | position:absolute; 13 | } 14 | */ 15 | 16 | @media screen, projection, print { 17 | .wrap { 18 | max-width: none; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/doclib/template/assets/images/arrows-up-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rovo89/XposedBridge/a535c02ed9dfd53683cc0274d9f95bcb6ffb9f79/app/doclib/template/assets/images/arrows-up-down.png -------------------------------------------------------------------------------- /app/doclib/template/assets/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rovo89/XposedBridge/a535c02ed9dfd53683cc0274d9f95bcb6ffb9f79/app/doclib/template/assets/images/favicon.ico -------------------------------------------------------------------------------- /app/doclib/template/assets/images/fullscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rovo89/XposedBridge/a535c02ed9dfd53683cc0274d9f95bcb6ffb9f79/app/doclib/template/assets/images/fullscreen.png -------------------------------------------------------------------------------- /app/doclib/template/assets/images/resizable-s2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rovo89/XposedBridge/a535c02ed9dfd53683cc0274d9f95bcb6ffb9f79/app/doclib/template/assets/images/resizable-s2.png -------------------------------------------------------------------------------- /app/doclib/template/assets/images/sprite-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rovo89/XposedBridge/a535c02ed9dfd53683cc0274d9f95bcb6ffb9f79/app/doclib/template/assets/images/sprite-2x.png -------------------------------------------------------------------------------- /app/doclib/template/assets/images/sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rovo89/XposedBridge/a535c02ed9dfd53683cc0274d9f95bcb6ffb9f79/app/doclib/template/assets/images/sprite.png -------------------------------------------------------------------------------- /app/doclib/template/assets/images/triangle-closed-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rovo89/XposedBridge/a535c02ed9dfd53683cc0274d9f95bcb6ffb9f79/app/doclib/template/assets/images/triangle-closed-small.png -------------------------------------------------------------------------------- /app/doclib/template/assets/images/triangle-closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rovo89/XposedBridge/a535c02ed9dfd53683cc0274d9f95bcb6ffb9f79/app/doclib/template/assets/images/triangle-closed.png -------------------------------------------------------------------------------- /app/doclib/template/assets/images/triangle-opened-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rovo89/XposedBridge/a535c02ed9dfd53683cc0274d9f95bcb6ffb9f79/app/doclib/template/assets/images/triangle-opened-small.png -------------------------------------------------------------------------------- /app/doclib/template/assets/images/triangle-opened.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rovo89/XposedBridge/a535c02ed9dfd53683cc0274d9f95bcb6ffb9f79/app/doclib/template/assets/images/triangle-opened.png -------------------------------------------------------------------------------- /app/doclib/template/assets/images/xposed_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rovo89/XposedBridge/a535c02ed9dfd53683cc0274d9f95bcb6ffb9f79/app/doclib/template/assets/images/xposed_logo.png -------------------------------------------------------------------------------- /app/doclib/template/assets/images/xposed_logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rovo89/XposedBridge/a535c02ed9dfd53683cc0274d9f95bcb6ffb9f79/app/doclib/template/assets/images/xposed_logo@2x.png -------------------------------------------------------------------------------- /app/doclib/template/classes.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | devsite> 5 | 6 | 13 | 14 | 15 | 16 |
17 | 18 |
19 |

20 |
21 | 22 |
23 |

These are the Xposed Framework API classes. See all API packages.

24 |
25 |    26 |
27 | 28 | 29 | 30 |

31 | 32 | 33 | 34 | 35 | 36 | 40 | 41 | 42 | 43 |
37 |   38 | 39 |
44 | 45 | 46 |
47 | 48 | 49 |
50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /app/doclib/template/components/masthead.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 15 |
16 | 17 | -------------------------------------------------------------------------------- /app/doclib/template/data.hdf: -------------------------------------------------------------------------------- 1 | template { 2 | which = normal 3 | } 4 | 5 | -------------------------------------------------------------------------------- /app/doclib/template/footer.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rovo89/XposedBridge/a535c02ed9dfd53683cc0274d9f95bcb6ffb9f79/app/doclib/template/footer.cs -------------------------------------------------------------------------------- /app/doclib/template/head_tag.cs: -------------------------------------------------------------------------------- 1 | 2 | 4 | 13 | 17 | 18 | 19 | 20 | 22 | 24 | 25 | <?cs 26 | if:page.title ?><?cs 27 | var:page.title ?> | <?cs 28 | /if ?>Xposed Framework API 29 | 30 | 31 | 35 | 39 | 44 | 45 | 46 | 47 | 48 | 50 | 51 | 52 | 53 | 60 | 62 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /app/doclib/template/header.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/doclib/template/hierarchy.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 21 | 22 | 23 | 24 |
25 | 26 |
27 |

28 |
29 | 30 |
31 | 32 |
33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 |    51 | 52 |   53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
ClassInterfaces
63 |
64 | 65 |
66 | 67 | 68 |
69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /app/doclib/template/index.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/doclib/template/jd_lists_unified.cs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/doclib/template/macros_override.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | Annotations: ", "") ?> 4 | 5 | 6 | 7 | 8 | 9 | Included in documentation by the annotations: 10 | 11 | @ 12 | 13 | ,   14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 32 | 33 | 34 | 35 |
29 |   30 | 31 |
36 | 37 | 38 | 41 | Added in API level 43 | -------------------------------------------------------------------------------- /app/doclib/template/navtree_data.cs: -------------------------------------------------------------------------------- 1 | var NAVTREE_DATA = 2 | 3 | ; 4 | -------------------------------------------------------------------------------- /app/doclib/template/nosidenavpage.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | devsite> 4 | 5 | 10 | 11 | 12 | 13 |
14 |
15 |
16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/doclib/template/package.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | devsite> 5 | 6 | 7 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |
21 |
22 | 23 | 24 |
25 |
26 | 27 |
28 | package 29 |

30 |
31 | 32 |
33 | 34 |
35 | 36 | 37 |
38 | 39 |
40 | 41 | 42 | 43 | 44 |

45 |
46 | 47 |
48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 |
59 | 60 | 61 |
62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /app/doclib/template/packages.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | devsite> 5 | 6 | 13 | 14 | 15 | 16 |
17 | 18 |
19 |

Overview

20 |
21 | 22 |
23 | 24 |
25 |

26 |
27 | 28 |

Packages Index:

29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |
39 | 40 |
41 | 42 | 43 |
44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /app/doclib/template/timestamp.cs: -------------------------------------------------------------------------------- 1 | var BUILD_TIMESTAMP = ""; 2 | -------------------------------------------------------------------------------- /app/doclib/template/todo.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <?cs var:page.title ?> 5 | 29 | 30 | 31 |

32 |

Overall

33 | 34 | 35 | 36 | 37 |
Errors
Percent Good
Total Comments
38 |

Package Summary

39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 |
PackageErrorsPercent GoodTotal
55 |

Class Summary

56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 |
ClassErrorsPercent GoodTotal
72 |

Detail

73 | 74 |

75 |

Errors:
76 | Total:
77 | Percent Good:

78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 |
87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /app/doclib/template/trailer.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rovo89/XposedBridge/a535c02ed9dfd53683cc0274d9f95bcb6ffb9f79/app/doclib/template/trailer.cs -------------------------------------------------------------------------------- /app/lint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /app/src/main/apacheCommonsLang/MODIFICATIONS.txt: -------------------------------------------------------------------------------- 1 | This is the original source code of the Apache Commons Lang library version 3.1 2 | as downloaded from http://commons.apache.org/lang/download_lang.cgi, except for 3 | these modifications: 4 | - Class MemberUtils changed to public 5 | - Method compareParameterTypes in MemberUtils changed to public 6 | - Prefix "external." for packages to avoid conflicts with other apps 7 | - Removed unused sub-packages for smaller file size: 8 | concurrent/ 9 | event/ 10 | math/ 11 | text/ 12 | time/ 13 | - Removed unused classes for smaller file size: 14 | AnnotationUtils.java 15 | BitField.java 16 | BooleanUtils.java 17 | CharEncoding.java 18 | CharRange.java 19 | CharSet.java 20 | CharSetUtils.java 21 | EnumUtils.java 22 | LocaleUtils.java 23 | RandomStringUtils.java 24 | Range.java 25 | SerializationException.java 26 | SerializationUtils.java 27 | StringEscapeUtils.java 28 | builder/StandardToStringStyle.java 29 | exception/ContextedException.java 30 | exception/ContextedRuntimeException.java 31 | exception/DefaultExceptionContext.java 32 | exception/ExceptionContext.java 33 | exception/ExceptionUtils.java 34 | mutable/MutableBoolean.java 35 | mutable/MutableByte.java 36 | mutable/MutableDouble.java 37 | mutable/MutableFloat.java 38 | mutable/MutableLong.java 39 | mutable/MutableObject.java 40 | mutable/MutableShort.java 41 | reflect/ConstructorUtils.java 42 | reflect/FieldUtils.java 43 | reflect/TypeUtils.java 44 | tuple/MutablePair.java 45 | -------------------------------------------------------------------------------- /app/src/main/apacheCommonsLang/NOTICE.txt: -------------------------------------------------------------------------------- 1 | Apache Commons Lang 2 | Copyright 2001-2011 The Apache Software Foundation 3 | 4 | This product includes software developed by 5 | The Apache Software Foundation (http://www.apache.org/). 6 | 7 | This product includes software from the Spring Framework, 8 | under the Apache License 2.0 (see: StringUtils.containsWhitespace()) 9 | -------------------------------------------------------------------------------- /app/src/main/apacheCommonsLang/RELEASE-NOTES.txt: -------------------------------------------------------------------------------- 1 | $Id: RELEASE-NOTES.txt 1199820 2011-11-09 16:14:52Z bayard $ 2 | 3 | Commons Lang Package 4 | Version 3.1 5 | Release Notes 6 | 7 | 8 | INTRODUCTION: 9 | 10 | This document contains the release notes for the 3.1 version of Apache Commons Lang. 11 | Commons Lang is a set of utility functions and reusable components that should be of use in any 12 | Java environment. 13 | 14 | Lang 3.0 and onwards now targets Java 5.0, making use of features that arrived with Java 5.0 such as generics, 15 | variable arguments, autoboxing, concurrency and formatted output. 16 | 17 | For the advice on upgrading from 2.x to 3.x, see the following page: 18 | 19 | http://commons.apache.org/lang/article3_0.html 20 | 21 | CHANGES IN 3.1 22 | ================ 23 | 24 | [LANG-760] Add API StringUtils.toString(byte[] intput, String charsetName) 25 | [LANG-756] Add APIs ClassUtils.isPrimitiveWrapper(Class) and isPrimitiveOrWrapper(Class) 26 | [LANG-758] Add an example with whitespace in StringUtils.defaultIfEmpty 27 | [LANG-752] Fix createLong() so it behaves like createInteger() 28 | [LANG-751] Include the actual type in the Validate.isInstance and isAssignableFrom exception messages 29 | [LANG-748] Deprecating chomp(String, String) 30 | [LANG-736] CharUtils static final array CHAR_STRING is not needed to compute CHAR_STRING_ARRAY 31 | [LANG-695] SystemUtils.IS_OS_UNIX doesn't recognize FreeBSD as a Unix system 32 | 33 | BUG FIXES IN 3.1 34 | ================== 35 | 36 | [LANG-749] Incorrect Bundle-SymbolicName in Manifest 37 | [LANG-746] NumberUtils does not handle upper-case hex: 0X and -0X 38 | [LANG-744] StringUtils throws java.security.AccessControlException on Google App Engine 39 | [LANG-741] Ant build has wrong component.name 40 | [LANG-698] Document that the Mutable numbers don't work as expected with String.format 41 | -------------------------------------------------------------------------------- /app/src/main/apacheCommonsLang/external/org/apache/commons/lang3/CharSequenceUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package external.org.apache.commons.lang3; 18 | 19 | /** 20 | *

Operations on {@link java.lang.CharSequence} that are 21 | * {@code null} safe.

22 | * 23 | * @see java.lang.CharSequence 24 | * @since 3.0 25 | * @version $Id: CharSequenceUtils.java 1199894 2011-11-09 17:53:59Z ggregory $ 26 | */ 27 | public class CharSequenceUtils { 28 | 29 | /** 30 | *

{@code CharSequenceUtils} instances should NOT be constructed in 31 | * standard programming.

32 | * 33 | *

This constructor is public to permit tools that require a JavaBean 34 | * instance to operate.

35 | */ 36 | public CharSequenceUtils() { 37 | super(); 38 | } 39 | 40 | //----------------------------------------------------------------------- 41 | /** 42 | *

Returns a new {@code CharSequence} that is a subsequence of this 43 | * sequence starting with the {@code char} value at the specified index.

44 | * 45 | *

This provides the {@code CharSequence} equivalent to {@link String#substring(int)}. 46 | * The length (in {@code char}) of the returned sequence is {@code length() - start}, 47 | * so if {@code start == end} then an empty sequence is returned.

48 | * 49 | * @param cs the specified subsequence, null returns null 50 | * @param start the start index, inclusive, valid 51 | * @return a new subsequence, may be null 52 | * @throws IndexOutOfBoundsException if {@code start} is negative or if 53 | * {@code start} is greater than {@code length()} 54 | */ 55 | public static CharSequence subSequence(CharSequence cs, int start) { 56 | return cs == null ? null : cs.subSequence(start, cs.length()); 57 | } 58 | 59 | //----------------------------------------------------------------------- 60 | /** 61 | *

Finds the first index in the {@code CharSequence} that matches the 62 | * specified character.

63 | * 64 | * @param cs the {@code CharSequence} to be processed, not null 65 | * @param searchChar the char to be searched for 66 | * @param start the start index, negative starts at the string start 67 | * @return the index where the search char was found, -1 if not found 68 | */ 69 | static int indexOf(CharSequence cs, int searchChar, int start) { 70 | if (cs instanceof String) { 71 | return ((String) cs).indexOf(searchChar, start); 72 | } else { 73 | int sz = cs.length(); 74 | if (start < 0) { 75 | start = 0; 76 | } 77 | for (int i = start; i < sz; i++) { 78 | if (cs.charAt(i) == searchChar) { 79 | return i; 80 | } 81 | } 82 | return -1; 83 | } 84 | } 85 | 86 | /** 87 | * Used by the indexOf(CharSequence methods) as a green implementation of indexOf. 88 | * 89 | * @param cs the {@code CharSequence} to be processed 90 | * @param searchChar the {@code CharSequence} to be searched for 91 | * @param start the start index 92 | * @return the index where the search sequence was found 93 | */ 94 | static int indexOf(CharSequence cs, CharSequence searchChar, int start) { 95 | return cs.toString().indexOf(searchChar.toString(), start); 96 | // if (cs instanceof String && searchChar instanceof String) { 97 | // // TODO: Do we assume searchChar is usually relatively small; 98 | // // If so then calling toString() on it is better than reverting to 99 | // // the green implementation in the else block 100 | // return ((String) cs).indexOf((String) searchChar, start); 101 | // } else { 102 | // // TODO: Implement rather than convert to String 103 | // return cs.toString().indexOf(searchChar.toString(), start); 104 | // } 105 | } 106 | 107 | /** 108 | *

Finds the last index in the {@code CharSequence} that matches the 109 | * specified character.

110 | * 111 | * @param cs the {@code CharSequence} to be processed 112 | * @param searchChar the char to be searched for 113 | * @param start the start index, negative returns -1, beyond length starts at end 114 | * @return the index where the search char was found, -1 if not found 115 | */ 116 | static int lastIndexOf(CharSequence cs, int searchChar, int start) { 117 | if (cs instanceof String) { 118 | return ((String) cs).lastIndexOf(searchChar, start); 119 | } else { 120 | int sz = cs.length(); 121 | if (start < 0) { 122 | return -1; 123 | } 124 | if (start >= sz) { 125 | start = sz - 1; 126 | } 127 | for (int i = start; i >= 0; --i) { 128 | if (cs.charAt(i) == searchChar) { 129 | return i; 130 | } 131 | } 132 | return -1; 133 | } 134 | } 135 | 136 | /** 137 | * Used by the lastIndexOf(CharSequence methods) as a green implementation of lastIndexOf 138 | * 139 | * @param cs the {@code CharSequence} to be processed 140 | * @param searchChar the {@code CharSequence} to be searched for 141 | * @param start the start index 142 | * @return the index where the search sequence was found 143 | */ 144 | static int lastIndexOf(CharSequence cs, CharSequence searchChar, int start) { 145 | return cs.toString().lastIndexOf(searchChar.toString(), start); 146 | // if (cs instanceof String && searchChar instanceof String) { 147 | // // TODO: Do we assume searchChar is usually relatively small; 148 | // // If so then calling toString() on it is better than reverting to 149 | // // the green implementation in the else block 150 | // return ((String) cs).lastIndexOf((String) searchChar, start); 151 | // } else { 152 | // // TODO: Implement rather than convert to String 153 | // return cs.toString().lastIndexOf(searchChar.toString(), start); 154 | // } 155 | } 156 | 157 | /** 158 | * Green implementation of toCharArray. 159 | * 160 | * @param cs the {@code CharSequence} to be processed 161 | * @return the resulting char array 162 | */ 163 | static char[] toCharArray(CharSequence cs) { 164 | if (cs instanceof String) { 165 | return ((String) cs).toCharArray(); 166 | } else { 167 | int sz = cs.length(); 168 | char[] array = new char[cs.length()]; 169 | for (int i = 0; i < sz; i++) { 170 | array[i] = cs.charAt(i); 171 | } 172 | return array; 173 | } 174 | } 175 | 176 | /** 177 | * Green implementation of regionMatches. 178 | * 179 | * @param cs the {@code CharSequence} to be processed 180 | * @param ignoreCase whether or not to be case insensitive 181 | * @param thisStart the index to start on the {@code cs} CharSequence 182 | * @param substring the {@code CharSequence} to be looked for 183 | * @param start the index to start on the {@code substring} CharSequence 184 | * @param length character length of the region 185 | * @return whether the region matched 186 | */ 187 | static boolean regionMatches(CharSequence cs, boolean ignoreCase, int thisStart, 188 | CharSequence substring, int start, int length) { 189 | if (cs instanceof String && substring instanceof String) { 190 | return ((String) cs).regionMatches(ignoreCase, thisStart, (String) substring, start, length); 191 | } else { 192 | // TODO: Implement rather than convert to String 193 | return cs.toString().regionMatches(ignoreCase, thisStart, substring.toString(), start, length); 194 | } 195 | } 196 | 197 | } 198 | -------------------------------------------------------------------------------- /app/src/main/apacheCommonsLang/external/org/apache/commons/lang3/JavaVersion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package external.org.apache.commons.lang3; 18 | 19 | /** 20 | *

An enum representing all the versions of the Java specification. 21 | * This is intended to mirror available values from the 22 | * java.specification.version System property.

23 | * 24 | * @since 3.0 25 | * @version $Id: $ 26 | */ 27 | public enum JavaVersion { 28 | 29 | /** 30 | * The Java version reported by Android. This is not an official Java version number. 31 | */ 32 | JAVA_0_9(1.5f, "0.9"), 33 | 34 | /** 35 | * Java 1.1. 36 | */ 37 | JAVA_1_1(1.1f, "1.1"), 38 | 39 | /** 40 | * Java 1.2. 41 | */ 42 | JAVA_1_2(1.2f, "1.2"), 43 | 44 | /** 45 | * Java 1.3. 46 | */ 47 | JAVA_1_3(1.3f, "1.3"), 48 | 49 | /** 50 | * Java 1.4. 51 | */ 52 | JAVA_1_4(1.4f, "1.4"), 53 | 54 | /** 55 | * Java 1.5. 56 | */ 57 | JAVA_1_5(1.5f, "1.5"), 58 | 59 | /** 60 | * Java 1.6. 61 | */ 62 | JAVA_1_6(1.6f, "1.6"), 63 | 64 | /** 65 | * Java 1.7. 66 | */ 67 | JAVA_1_7(1.7f, "1.7"), 68 | 69 | /** 70 | * Java 1.8. 71 | */ 72 | JAVA_1_8(1.8f, "1.8"); 73 | 74 | /** 75 | * The float value. 76 | */ 77 | private float value; 78 | /** 79 | * The standard name. 80 | */ 81 | private String name; 82 | 83 | /** 84 | * Constructor. 85 | * 86 | * @param value the float value 87 | * @param name the standard name, not null 88 | */ 89 | JavaVersion(final float value, final String name) { 90 | this.value = value; 91 | this.name = name; 92 | } 93 | 94 | //----------------------------------------------------------------------- 95 | /** 96 | *

Whether this version of Java is at least the version of Java passed in.

97 | * 98 | *

For example:
99 | * {@code myVersion.atLeast(JavaVersion.JAVA_1_4)}

100 | * 101 | * @param requiredVersion the version to check against, not null 102 | * @return true if this version is equal to or greater than the specified version 103 | */ 104 | public boolean atLeast(JavaVersion requiredVersion) { 105 | return this.value >= requiredVersion.value; 106 | } 107 | 108 | /** 109 | * Transforms the given string with a Java version number to the 110 | * corresponding constant of this enumeration class. This method is used 111 | * internally. 112 | * 113 | * @param nom the Java version as string 114 | * @return the corresponding enumeration constant or null if the 115 | * version is unknown 116 | */ 117 | // helper for static importing 118 | static JavaVersion getJavaVersion(final String nom) { 119 | return get(nom); 120 | } 121 | 122 | /** 123 | * Transforms the given string with a Java version number to the 124 | * corresponding constant of this enumeration class. This method is used 125 | * internally. 126 | * 127 | * @param nom the Java version as string 128 | * @return the corresponding enumeration constant or null if the 129 | * version is unknown 130 | */ 131 | static JavaVersion get(final String nom) { 132 | if ("0.9".equals(nom)) { 133 | return JAVA_0_9; 134 | } else if ("1.1".equals(nom)) { 135 | return JAVA_1_1; 136 | } else if ("1.2".equals(nom)) { 137 | return JAVA_1_2; 138 | } else if ("1.3".equals(nom)) { 139 | return JAVA_1_3; 140 | } else if ("1.4".equals(nom)) { 141 | return JAVA_1_4; 142 | } else if ("1.5".equals(nom)) { 143 | return JAVA_1_5; 144 | } else if ("1.6".equals(nom)) { 145 | return JAVA_1_6; 146 | } else if ("1.7".equals(nom)) { 147 | return JAVA_1_7; 148 | } else if ("1.8".equals(nom)) { 149 | return JAVA_1_8; 150 | } else { 151 | return null; 152 | } 153 | } 154 | 155 | //----------------------------------------------------------------------- 156 | /** 157 | *

The string value is overridden to return the standard name.

158 | * 159 | *

For example, "1.5".

160 | * 161 | * @return the name, not null 162 | */ 163 | @Override 164 | public String toString() { 165 | return name; 166 | } 167 | 168 | } 169 | -------------------------------------------------------------------------------- /app/src/main/apacheCommonsLang/external/org/apache/commons/lang3/builder/Builder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package external.org.apache.commons.lang3.builder; 18 | 19 | /** 20 | *

21 | * The Builder interface is designed to designate a class as a builder 22 | * object in the Builder design pattern. Builders are capable of creating and 23 | * configuring objects or results that normally take multiple steps to construct 24 | * or are very complex to derive. 25 | *

26 | * 27 | *

28 | * The builder interface defines a single method, {@link #build()}, that 29 | * classes must implement. The result of this method should be the final 30 | * configured object or result after all building operations are performed. 31 | *

32 | * 33 | *

34 | * It is a recommended practice that the methods supplied to configure the 35 | * object or result being built return a reference to {@code this} so that 36 | * method calls can be chained together. 37 | *

38 | * 39 | *

40 | * Example Builder: 41 | *

42 |  * class FontBuilder implements Builder<Font> {
43 |  *     private Font font;
44 |  *     
45 |  *     public FontBuilder(String fontName) {
46 |  *         this.font = new Font(fontName, Font.PLAIN, 12);
47 |  *     }
48 |  * 
49 |  *     public FontBuilder bold() {
50 |  *         this.font = this.font.deriveFont(Font.BOLD);
51 |  *         return this; // Reference returned so calls can be chained
52 |  *     }
53 |  *     
54 |  *     public FontBuilder size(float pointSize) {
55 |  *         this.font = this.font.deriveFont(pointSize);
56 |  *         return this; // Reference returned so calls can be chained
57 |  *     }
58 |  * 
59 |  *     // Other Font construction methods
60 |  * 
61 |  *     public Font build() {
62 |  *         return this.font;
63 |  *     }
64 |  * }
65 |  * 
66 | * 67 | * Example Builder Usage: 68 | *
69 |  * Font bold14ptSansSerifFont = new FontBuilder(Font.SANS_SERIF).bold()
70 |  *                                                              .size(14.0f)
71 |  *                                                              .build();
72 |  * 
73 | *

74 | * 75 | * @param the type of object that the builder will construct or compute. 76 | * 77 | * @since 3.0 78 | * @version $Id: Builder.java 1088899 2011-04-05 05:31:27Z bayard $ 79 | */ 80 | public interface Builder { 81 | 82 | /** 83 | * Returns a reference to the object being constructed or result being 84 | * calculated by the builder. 85 | * 86 | * @return the object constructed or result calculated by the builder. 87 | */ 88 | public T build(); 89 | } 90 | -------------------------------------------------------------------------------- /app/src/main/apacheCommonsLang/external/org/apache/commons/lang3/builder/IDKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | */ 18 | 19 | package external.org.apache.commons.lang3.builder; 20 | 21 | // adapted from org.apache.axis.utils.IDKey 22 | 23 | /** 24 | * Wrap an identity key (System.identityHashCode()) 25 | * so that an object can only be equal() to itself. 26 | * 27 | * This is necessary to disambiguate the occasional duplicate 28 | * identityHashCodes that can occur. 29 | * 30 | */ 31 | final class IDKey { 32 | private final Object value; 33 | private final int id; 34 | 35 | /** 36 | * Constructor for IDKey 37 | * @param _value The value 38 | */ 39 | public IDKey(Object _value) { 40 | // This is the Object hashcode 41 | id = System.identityHashCode(_value); 42 | // There have been some cases (LANG-459) that return the 43 | // same identity hash code for different objects. So 44 | // the value is also added to disambiguate these cases. 45 | value = _value; 46 | } 47 | 48 | /** 49 | * returns hashcode - i.e. the system identity hashcode. 50 | * @return the hashcode 51 | */ 52 | @Override 53 | public int hashCode() { 54 | return id; 55 | } 56 | 57 | /** 58 | * checks if instances are equal 59 | * @param other The other object to compare to 60 | * @return if the instances are for the same object 61 | */ 62 | @Override 63 | public boolean equals(Object other) { 64 | if (!(other instanceof IDKey)) { 65 | return false; 66 | } 67 | IDKey idKey = (IDKey) other; 68 | if (id != idKey.id) { 69 | return false; 70 | } 71 | // Note that identity equals is used. 72 | return value == idKey.value; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /app/src/main/apacheCommonsLang/external/org/apache/commons/lang3/builder/package.html: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | Assists in creating consistent equals(Object), toString(), 20 | hashCode(), and compareTo(Object) methods. 21 | @see java.lang.Object#equals(Object) 22 | @see java.lang.Object#toString() 23 | @see java.lang.Object#hashCode() 24 | @see java.lang.Comparable#compareTo(Object) 25 | @since 1.0 26 |

These classes are not thread-safe.

27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/apacheCommonsLang/external/org/apache/commons/lang3/exception/CloneFailedException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package external.org.apache.commons.lang3.exception; 18 | 19 | /** 20 | * Exception thrown when a clone cannot be created. In contrast to 21 | * {@link CloneNotSupportedException} this is a {@link RuntimeException}. 22 | * 23 | * @since 3.0 24 | */ 25 | public class CloneFailedException extends RuntimeException { 26 | // ~ Static fields/initializers --------------------------------------------- 27 | 28 | private static final long serialVersionUID = 20091223L; 29 | 30 | // ~ Constructors ----------------------------------------------------------- 31 | 32 | /** 33 | * Constructs a CloneFailedException. 34 | * 35 | * @param message description of the exception 36 | * @since upcoming 37 | */ 38 | public CloneFailedException(final String message) { 39 | super(message); 40 | } 41 | 42 | /** 43 | * Constructs a CloneFailedException. 44 | * 45 | * @param cause cause of the exception 46 | * @since upcoming 47 | */ 48 | public CloneFailedException(final Throwable cause) { 49 | super(cause); 50 | } 51 | 52 | /** 53 | * Constructs a CloneFailedException. 54 | * 55 | * @param message description of the exception 56 | * @param cause cause of the exception 57 | * @since upcoming 58 | */ 59 | public CloneFailedException(final String message, final Throwable cause) { 60 | super(message, cause); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /app/src/main/apacheCommonsLang/external/org/apache/commons/lang3/exception/package.html: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | Provides functionality for Exceptions. 20 |

Contains the concept of an exception with context i.e. such an exception 21 | will contain a map with keys and values. This provides an easy way to pass valuable 22 | state information at exception time in useful form to a calling process.

23 |

Lastly, {@link org.apache.commons.lang3.exception.ExceptionUtils} 24 | also contains Throwable manipulation and examination routines.

25 | @since 1.0 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/apacheCommonsLang/external/org/apache/commons/lang3/mutable/Mutable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package external.org.apache.commons.lang3.mutable; 19 | 20 | /** 21 | * Provides mutable access to a value. 22 | *

23 | * Mutable is used as a generic interface to the implementations in this package. 24 | *

25 | * A typical use case would be to enable a primitive or string to be passed to a method and allow that method to 26 | * effectively change the value of the primitive/string. Another use case is to store a frequently changing primitive in 27 | * a collection (for example a total in a map) without needing to create new Integer/Long wrapper objects. 28 | * 29 | * @since 2.1 30 | * @param the type to set and get 31 | * @version $Id: Mutable.java 1153213 2011-08-02 17:35:39Z ggregory $ 32 | */ 33 | public interface Mutable { 34 | 35 | /** 36 | * Gets the value of this mutable. 37 | * 38 | * @return the stored value 39 | */ 40 | T getValue(); 41 | 42 | /** 43 | * Sets the value of this mutable. 44 | * 45 | * @param value 46 | * the value to store 47 | * @throws NullPointerException 48 | * if the object is null and null is invalid 49 | * @throws ClassCastException 50 | * if the type is invalid 51 | */ 52 | void setValue(T value); 53 | 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/apacheCommonsLang/external/org/apache/commons/lang3/mutable/MutableInt.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package external.org.apache.commons.lang3.mutable; 18 | 19 | /** 20 | * A mutable int wrapper. 21 | *

22 | * Note that as MutableInt does not extend Integer, it is not treated by String.format as an Integer parameter. 23 | * 24 | * @see Integer 25 | * @since 2.1 26 | * @version $Id: MutableInt.java 1160571 2011-08-23 07:36:08Z bayard $ 27 | */ 28 | public class MutableInt extends Number implements Comparable, Mutable { 29 | 30 | /** 31 | * Required for serialization support. 32 | * 33 | * @see java.io.Serializable 34 | */ 35 | private static final long serialVersionUID = 512176391864L; 36 | 37 | /** The mutable value. */ 38 | private int value; 39 | 40 | /** 41 | * Constructs a new MutableInt with the default value of zero. 42 | */ 43 | public MutableInt() { 44 | super(); 45 | } 46 | 47 | /** 48 | * Constructs a new MutableInt with the specified value. 49 | * 50 | * @param value the initial value to store 51 | */ 52 | public MutableInt(int value) { 53 | super(); 54 | this.value = value; 55 | } 56 | 57 | /** 58 | * Constructs a new MutableInt with the specified value. 59 | * 60 | * @param value the initial value to store, not null 61 | * @throws NullPointerException if the object is null 62 | */ 63 | public MutableInt(Number value) { 64 | super(); 65 | this.value = value.intValue(); 66 | } 67 | 68 | /** 69 | * Constructs a new MutableInt parsing the given string. 70 | * 71 | * @param value the string to parse, not null 72 | * @throws NumberFormatException if the string cannot be parsed into an int 73 | * @since 2.5 74 | */ 75 | public MutableInt(String value) throws NumberFormatException { 76 | super(); 77 | this.value = Integer.parseInt(value); 78 | } 79 | 80 | //----------------------------------------------------------------------- 81 | /** 82 | * Gets the value as a Integer instance. 83 | * 84 | * @return the value as a Integer, never null 85 | */ 86 | public Integer getValue() { 87 | return Integer.valueOf(this.value); 88 | } 89 | 90 | /** 91 | * Sets the value. 92 | * 93 | * @param value the value to set 94 | */ 95 | public void setValue(int value) { 96 | this.value = value; 97 | } 98 | 99 | /** 100 | * Sets the value from any Number instance. 101 | * 102 | * @param value the value to set, not null 103 | * @throws NullPointerException if the object is null 104 | */ 105 | public void setValue(Number value) { 106 | this.value = value.intValue(); 107 | } 108 | 109 | //----------------------------------------------------------------------- 110 | /** 111 | * Increments the value. 112 | * 113 | * @since Commons Lang 2.2 114 | */ 115 | public void increment() { 116 | value++; 117 | } 118 | 119 | /** 120 | * Decrements the value. 121 | * 122 | * @since Commons Lang 2.2 123 | */ 124 | public void decrement() { 125 | value--; 126 | } 127 | 128 | //----------------------------------------------------------------------- 129 | /** 130 | * Adds a value to the value of this instance. 131 | * 132 | * @param operand the value to add, not null 133 | * @since Commons Lang 2.2 134 | */ 135 | public void add(int operand) { 136 | this.value += operand; 137 | } 138 | 139 | /** 140 | * Adds a value to the value of this instance. 141 | * 142 | * @param operand the value to add, not null 143 | * @throws NullPointerException if the object is null 144 | * @since Commons Lang 2.2 145 | */ 146 | public void add(Number operand) { 147 | this.value += operand.intValue(); 148 | } 149 | 150 | /** 151 | * Subtracts a value from the value of this instance. 152 | * 153 | * @param operand the value to subtract, not null 154 | * @since Commons Lang 2.2 155 | */ 156 | public void subtract(int operand) { 157 | this.value -= operand; 158 | } 159 | 160 | /** 161 | * Subtracts a value from the value of this instance. 162 | * 163 | * @param operand the value to subtract, not null 164 | * @throws NullPointerException if the object is null 165 | * @since Commons Lang 2.2 166 | */ 167 | public void subtract(Number operand) { 168 | this.value -= operand.intValue(); 169 | } 170 | 171 | //----------------------------------------------------------------------- 172 | // shortValue and byteValue rely on Number implementation 173 | /** 174 | * Returns the value of this MutableInt as an int. 175 | * 176 | * @return the numeric value represented by this object after conversion to type int. 177 | */ 178 | @Override 179 | public int intValue() { 180 | return value; 181 | } 182 | 183 | /** 184 | * Returns the value of this MutableInt as a long. 185 | * 186 | * @return the numeric value represented by this object after conversion to type long. 187 | */ 188 | @Override 189 | public long longValue() { 190 | return value; 191 | } 192 | 193 | /** 194 | * Returns the value of this MutableInt as a float. 195 | * 196 | * @return the numeric value represented by this object after conversion to type float. 197 | */ 198 | @Override 199 | public float floatValue() { 200 | return value; 201 | } 202 | 203 | /** 204 | * Returns the value of this MutableInt as a double. 205 | * 206 | * @return the numeric value represented by this object after conversion to type double. 207 | */ 208 | @Override 209 | public double doubleValue() { 210 | return value; 211 | } 212 | 213 | //----------------------------------------------------------------------- 214 | /** 215 | * Gets this mutable as an instance of Integer. 216 | * 217 | * @return a Integer instance containing the value from this mutable, never null 218 | */ 219 | public Integer toInteger() { 220 | return Integer.valueOf(intValue()); 221 | } 222 | 223 | //----------------------------------------------------------------------- 224 | /** 225 | * Compares this object to the specified object. The result is true if and only if the argument is 226 | * not null and is a MutableInt object that contains the same int value 227 | * as this object. 228 | * 229 | * @param obj the object to compare with, null returns false 230 | * @return true if the objects are the same; false otherwise. 231 | */ 232 | @Override 233 | public boolean equals(Object obj) { 234 | if (obj instanceof MutableInt) { 235 | return value == ((MutableInt) obj).intValue(); 236 | } 237 | return false; 238 | } 239 | 240 | /** 241 | * Returns a suitable hash code for this mutable. 242 | * 243 | * @return a suitable hash code 244 | */ 245 | @Override 246 | public int hashCode() { 247 | return value; 248 | } 249 | 250 | //----------------------------------------------------------------------- 251 | /** 252 | * Compares this mutable to another in ascending order. 253 | * 254 | * @param other the other mutable to compare to, not null 255 | * @return negative if this is less, zero if equal, positive if greater 256 | */ 257 | public int compareTo(MutableInt other) { 258 | int anotherVal = other.value; 259 | return value < anotherVal ? -1 : (value == anotherVal ? 0 : 1); 260 | } 261 | 262 | //----------------------------------------------------------------------- 263 | /** 264 | * Returns the String value of this mutable. 265 | * 266 | * @return the mutable value as a string 267 | */ 268 | @Override 269 | public String toString() { 270 | return String.valueOf(value); 271 | } 272 | 273 | } 274 | -------------------------------------------------------------------------------- /app/src/main/apacheCommonsLang/external/org/apache/commons/lang3/mutable/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 24 | 25 | Provides typed mutable wrappers to primitive values and Object. 26 | @since 2.1 27 |

These classes are not thread-safe.

28 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/apacheCommonsLang/external/org/apache/commons/lang3/overview.html: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 |

20 | This document is the API specification for the Apache Commons Lang library. 21 |

22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/apacheCommonsLang/external/org/apache/commons/lang3/package.html: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | Provides highly reusable static utility methods, chiefly concerned 20 | with adding value to the {@link java.lang} classes. 21 | @since 1.0 22 |

Most of these classes are immutable and thus thread-safe. 23 | However Charset is not currently guaranteed thread-safe under all circumstances.

24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/apacheCommonsLang/external/org/apache/commons/lang3/reflect/MemberUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package external.org.apache.commons.lang3.reflect; 18 | 19 | import java.lang.reflect.AccessibleObject; 20 | import java.lang.reflect.Member; 21 | import java.lang.reflect.Modifier; 22 | 23 | import external.org.apache.commons.lang3.ClassUtils; 24 | 25 | /** 26 | * Contains common code for working with Methods/Constructors, extracted and 27 | * refactored from MethodUtils when it was imported from Commons 28 | * BeanUtils. 29 | * 30 | * @since 2.5 31 | * @version $Id: MemberUtils.java 1143537 2011-07-06 19:30:22Z joehni $ 32 | */ 33 | public abstract class MemberUtils { 34 | // TODO extract an interface to implement compareParameterSets(...)? 35 | 36 | private static final int ACCESS_TEST = Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE; 37 | 38 | /** Array of primitive number types ordered by "promotability" */ 39 | private static final Class[] ORDERED_PRIMITIVE_TYPES = { Byte.TYPE, Short.TYPE, 40 | Character.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE }; 41 | 42 | /** 43 | * XXX Default access superclass workaround 44 | * 45 | * When a public class has a default access superclass with public members, 46 | * these members are accessible. Calling them from compiled code works fine. 47 | * Unfortunately, on some JVMs, using reflection to invoke these members 48 | * seems to (wrongly) prevent access even when the modifier is public. 49 | * Calling setAccessible(true) solves the problem but will only work from 50 | * sufficiently privileged code. Better workarounds would be gratefully 51 | * accepted. 52 | * @param o the AccessibleObject to set as accessible 53 | */ 54 | static void setAccessibleWorkaround(AccessibleObject o) { 55 | if (o == null || o.isAccessible()) { 56 | return; 57 | } 58 | Member m = (Member) o; 59 | if (Modifier.isPublic(m.getModifiers()) 60 | && isPackageAccess(m.getDeclaringClass().getModifiers())) { 61 | try { 62 | o.setAccessible(true); 63 | } catch (SecurityException e) { // NOPMD 64 | // ignore in favor of subsequent IllegalAccessException 65 | } 66 | } 67 | } 68 | 69 | /** 70 | * Returns whether a given set of modifiers implies package access. 71 | * @param modifiers to test 72 | * @return true unless package/protected/private modifier detected 73 | */ 74 | static boolean isPackageAccess(int modifiers) { 75 | return (modifiers & ACCESS_TEST) == 0; 76 | } 77 | 78 | /** 79 | * Returns whether a Member is accessible. 80 | * @param m Member to check 81 | * @return true if m is accessible 82 | */ 83 | static boolean isAccessible(Member m) { 84 | return m != null && Modifier.isPublic(m.getModifiers()) && !m.isSynthetic(); 85 | } 86 | 87 | /** 88 | * Compares the relative fitness of two sets of parameter types in terms of 89 | * matching a third set of runtime parameter types, such that a list ordered 90 | * by the results of the comparison would return the best match first 91 | * (least). 92 | * 93 | * @param left the "left" parameter set 94 | * @param right the "right" parameter set 95 | * @param actual the runtime parameter types to match against 96 | * left/right 97 | * @return int consistent with compare semantics 98 | */ 99 | public static int compareParameterTypes(Class[] left, Class[] right, Class[] actual) { 100 | float leftCost = getTotalTransformationCost(actual, left); 101 | float rightCost = getTotalTransformationCost(actual, right); 102 | return leftCost < rightCost ? -1 : rightCost < leftCost ? 1 : 0; 103 | } 104 | 105 | /** 106 | * Returns the sum of the object transformation cost for each class in the 107 | * source argument list. 108 | * @param srcArgs The source arguments 109 | * @param destArgs The destination arguments 110 | * @return The total transformation cost 111 | */ 112 | private static float getTotalTransformationCost(Class[] srcArgs, Class[] destArgs) { 113 | float totalCost = 0.0f; 114 | for (int i = 0; i < srcArgs.length; i++) { 115 | Class srcClass, destClass; 116 | srcClass = srcArgs[i]; 117 | destClass = destArgs[i]; 118 | totalCost += getObjectTransformationCost(srcClass, destClass); 119 | } 120 | return totalCost; 121 | } 122 | 123 | /** 124 | * Gets the number of steps required needed to turn the source class into 125 | * the destination class. This represents the number of steps in the object 126 | * hierarchy graph. 127 | * @param srcClass The source class 128 | * @param destClass The destination class 129 | * @return The cost of transforming an object 130 | */ 131 | private static float getObjectTransformationCost(Class srcClass, Class destClass) { 132 | if (destClass.isPrimitive()) { 133 | return getPrimitivePromotionCost(srcClass, destClass); 134 | } 135 | float cost = 0.0f; 136 | while (srcClass != null && !destClass.equals(srcClass)) { 137 | if (destClass.isInterface() && ClassUtils.isAssignable(srcClass, destClass)) { 138 | // slight penalty for interface match. 139 | // we still want an exact match to override an interface match, 140 | // but 141 | // an interface match should override anything where we have to 142 | // get a superclass. 143 | cost += 0.25f; 144 | break; 145 | } 146 | cost++; 147 | srcClass = srcClass.getSuperclass(); 148 | } 149 | /* 150 | * If the destination class is null, we've travelled all the way up to 151 | * an Object match. We'll penalize this by adding 1.5 to the cost. 152 | */ 153 | if (srcClass == null) { 154 | cost += 1.5f; 155 | } 156 | return cost; 157 | } 158 | 159 | /** 160 | * Gets the number of steps required to promote a primitive number to another 161 | * type. 162 | * @param srcClass the (primitive) source class 163 | * @param destClass the (primitive) destination class 164 | * @return The cost of promoting the primitive 165 | */ 166 | private static float getPrimitivePromotionCost(final Class srcClass, final Class destClass) { 167 | float cost = 0.0f; 168 | Class cls = srcClass; 169 | if (!cls.isPrimitive()) { 170 | // slight unwrapping penalty 171 | cost += 0.1f; 172 | cls = ClassUtils.wrapperToPrimitive(cls); 173 | } 174 | for (int i = 0; cls != destClass && i < ORDERED_PRIMITIVE_TYPES.length; i++) { 175 | if (cls == ORDERED_PRIMITIVE_TYPES[i]) { 176 | cost += 0.1f; 177 | if (i < ORDERED_PRIMITIVE_TYPES.length - 1) { 178 | cls = ORDERED_PRIMITIVE_TYPES[i + 1]; 179 | } 180 | } 181 | } 182 | return cost; 183 | } 184 | 185 | } 186 | -------------------------------------------------------------------------------- /app/src/main/apacheCommonsLang/external/org/apache/commons/lang3/reflect/package.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 24 | 25 | Accumulates common high-level uses of the java.lang.reflect APIs. 26 | @since 3.0 27 |

These classes are immutable, and therefore thread-safe.

28 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/apacheCommonsLang/external/org/apache/commons/lang3/tuple/ImmutablePair.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package external.org.apache.commons.lang3.tuple; 18 | 19 | /** 20 | *

An immutable pair consisting of two {@code Object} elements.

21 | * 22 | *

Although the implementation is immutable, there is no restriction on the objects 23 | * that may be stored. If mutable objects are stored in the pair, then the pair 24 | * itself effectively becomes mutable. The class is also not {@code final}, so a subclass 25 | * could add undesirable behaviour.

26 | * 27 | *

#ThreadSafe# if the objects are threadsafe

28 | * 29 | * @param the left element type 30 | * @param the right element type 31 | * 32 | * @since Lang 3.0 33 | * @version $Id: ImmutablePair.java 1127544 2011-05-25 14:35:42Z scolebourne $ 34 | */ 35 | public final class ImmutablePair extends Pair { 36 | 37 | /** Serialization version */ 38 | private static final long serialVersionUID = 4954918890077093841L; 39 | 40 | /** Left object */ 41 | public final L left; 42 | /** Right object */ 43 | public final R right; 44 | 45 | /** 46 | *

Obtains an immutable pair of from two objects inferring the generic types.

47 | * 48 | *

This factory allows the pair to be created using inference to 49 | * obtain the generic types.

50 | * 51 | * @param the left element type 52 | * @param the right element type 53 | * @param left the left element, may be null 54 | * @param right the right element, may be null 55 | * @return a pair formed from the two parameters, not null 56 | */ 57 | public static ImmutablePair of(L left, R right) { 58 | return new ImmutablePair(left, right); 59 | } 60 | 61 | /** 62 | * Create a new pair instance. 63 | * 64 | * @param left the left value, may be null 65 | * @param right the right value, may be null 66 | */ 67 | public ImmutablePair(L left, R right) { 68 | super(); 69 | this.left = left; 70 | this.right = right; 71 | } 72 | 73 | //----------------------------------------------------------------------- 74 | /** 75 | * {@inheritDoc} 76 | */ 77 | @Override 78 | public L getLeft() { 79 | return left; 80 | } 81 | 82 | /** 83 | * {@inheritDoc} 84 | */ 85 | @Override 86 | public R getRight() { 87 | return right; 88 | } 89 | 90 | /** 91 | *

Throws {@code UnsupportedOperationException}.

92 | * 93 | *

This pair is immutable, so this operation is not supported.

94 | * 95 | * @param value the value to set 96 | * @return never 97 | * @throws UnsupportedOperationException as this operation is not supported 98 | */ 99 | public R setValue(R value) { 100 | throw new UnsupportedOperationException(); 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /app/src/main/apacheCommonsLang/external/org/apache/commons/lang3/tuple/Pair.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package external.org.apache.commons.lang3.tuple; 18 | 19 | import java.io.Serializable; 20 | import java.util.Map; 21 | 22 | 23 | import external.org.apache.commons.lang3.ObjectUtils; 24 | import external.org.apache.commons.lang3.builder.CompareToBuilder; 25 | 26 | /** 27 | *

A pair consisting of two elements.

28 | * 29 | *

This class is an abstract implementation defining the basic API. 30 | * It refers to the elements as 'left' and 'right'. It also implements the 31 | * {@code Map.Entry} interface where the key is 'left' and the value is 'right'.

32 | * 33 | *

Subclass implementations may be mutable or immutable. 34 | * However, there is no restriction on the type of the stored objects that may be stored. 35 | * If mutable objects are stored in the pair, then the pair itself effectively becomes mutable.

36 | * 37 | * @param the left element type 38 | * @param the right element type 39 | * 40 | * @since Lang 3.0 41 | * @version $Id: Pair.java 1142401 2011-07-03 08:30:12Z bayard $ 42 | */ 43 | public abstract class Pair implements Map.Entry, Comparable>, Serializable { 44 | 45 | /** Serialization version */ 46 | private static final long serialVersionUID = 4954918890077093841L; 47 | 48 | /** 49 | *

Obtains an immutable pair of from two objects inferring the generic types.

50 | * 51 | *

This factory allows the pair to be created using inference to 52 | * obtain the generic types.

53 | * 54 | * @param the left element type 55 | * @param the right element type 56 | * @param left the left element, may be null 57 | * @param right the right element, may be null 58 | * @return a pair formed from the two parameters, not null 59 | */ 60 | public static Pair of(L left, R right) { 61 | return new ImmutablePair(left, right); 62 | } 63 | 64 | //----------------------------------------------------------------------- 65 | /** 66 | *

Gets the left element from this pair.

67 | * 68 | *

When treated as a key-value pair, this is the key.

69 | * 70 | * @return the left element, may be null 71 | */ 72 | public abstract L getLeft(); 73 | 74 | /** 75 | *

Gets the right element from this pair.

76 | * 77 | *

When treated as a key-value pair, this is the value.

78 | * 79 | * @return the right element, may be null 80 | */ 81 | public abstract R getRight(); 82 | 83 | /** 84 | *

Gets the key from this pair.

85 | * 86 | *

This method implements the {@code Map.Entry} interface returning the 87 | * left element as the key.

88 | * 89 | * @return the left element as the key, may be null 90 | */ 91 | public final L getKey() { 92 | return getLeft(); 93 | } 94 | 95 | /** 96 | *

Gets the value from this pair.

97 | * 98 | *

This method implements the {@code Map.Entry} interface returning the 99 | * right element as the value.

100 | * 101 | * @return the right element as the value, may be null 102 | */ 103 | public R getValue() { 104 | return getRight(); 105 | } 106 | 107 | //----------------------------------------------------------------------- 108 | /** 109 | *

Compares the pair based on the left element followed by the right element. 110 | * The types must be {@code Comparable}.

111 | * 112 | * @param other the other pair, not null 113 | * @return negative if this is less, zero if equal, positive if greater 114 | */ 115 | public int compareTo(Pair other) { 116 | return new CompareToBuilder().append(getLeft(), other.getLeft()) 117 | .append(getRight(), other.getRight()).toComparison(); 118 | } 119 | 120 | /** 121 | *

Compares this pair to another based on the two elements.

122 | * 123 | * @param obj the object to compare to, null returns false 124 | * @return true if the elements of the pair are equal 125 | */ 126 | @Override 127 | public boolean equals(Object obj) { 128 | if (obj == this) { 129 | return true; 130 | } 131 | if (obj instanceof Map.Entry) { 132 | Map.Entry other = (Map.Entry) obj; 133 | return ObjectUtils.equals(getKey(), other.getKey()) 134 | && ObjectUtils.equals(getValue(), other.getValue()); 135 | } 136 | return false; 137 | } 138 | 139 | /** 140 | *

Returns a suitable hash code. 141 | * The hash code follows the definition in {@code Map.Entry}.

142 | * 143 | * @return the hash code 144 | */ 145 | @Override 146 | public int hashCode() { 147 | // see Map.Entry API specification 148 | return (getKey() == null ? 0 : getKey().hashCode()) ^ 149 | (getValue() == null ? 0 : getValue().hashCode()); 150 | } 151 | 152 | /** 153 | *

Returns a String representation of this pair using the format {@code ($left,$right)}.

154 | * 155 | * @return a string describing this object, not null 156 | */ 157 | @Override 158 | public String toString() { 159 | return new StringBuilder().append('(').append(getLeft()).append(',').append(getRight()).append(')').toString(); 160 | } 161 | 162 | /** 163 | *

Formats the receiver using the given format.

164 | * 165 | *

This uses {@link java.util.Formattable} to perform the formatting. Two variables may 166 | * be used to embed the left and right elements. Use {@code %1$s} for the left 167 | * element (key) and {@code %2$s} for the right element (value). 168 | * The default format used by {@code toString()} is {@code (%1$s,%2$s)}.

169 | * 170 | * @param format the format string, optionally containing {@code %1$s} and {@code %2$s}, not null 171 | * @return the formatted string, not null 172 | */ 173 | public String toString(String format) { 174 | return String.format(format, getLeft(), getRight()); 175 | } 176 | 177 | } 178 | -------------------------------------------------------------------------------- /app/src/main/apacheCommonsLang/external/org/apache/commons/lang3/tuple/package.html: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | Tuple classes, starting with a Pair class in version 3.0. 20 | @since 3.0 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/java/android/app/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Contains {@link android.app.AndroidAppHelper} with various methods for information about the current app. 3 | */ 4 | package android.app; 5 | -------------------------------------------------------------------------------- /app/src/main/java/android/content/res/XModuleResources.java: -------------------------------------------------------------------------------- 1 | package android.content.res; 2 | 3 | import android.app.AndroidAppHelper; 4 | import android.util.DisplayMetrics; 5 | 6 | import de.robv.android.xposed.IXposedHookInitPackageResources; 7 | import de.robv.android.xposed.IXposedHookZygoteInit; 8 | import de.robv.android.xposed.IXposedHookZygoteInit.StartupParam; 9 | import de.robv.android.xposed.callbacks.XC_InitPackageResources.InitPackageResourcesParam; 10 | 11 | /** 12 | * Provides access to resources from a certain path (usually the module's own path). 13 | */ 14 | public class XModuleResources extends Resources { 15 | private XModuleResources(AssetManager assets, DisplayMetrics metrics, Configuration config) { 16 | super(assets, metrics, config); 17 | } 18 | 19 | /** 20 | * Creates a new instance. 21 | * 22 | *

This is usually called with {@link StartupParam#modulePath} from 23 | * {@link IXposedHookZygoteInit#initZygote} and {@link InitPackageResourcesParam#res} from 24 | * {@link IXposedHookInitPackageResources#handleInitPackageResources} (or {@code null} for 25 | * system-wide replacements). 26 | * 27 | * @param path The path to the APK from which the resources should be loaded. 28 | * @param origRes The resources object from which settings like the display metrics and the 29 | * configuration should be copied. May be {@code null}. 30 | */ 31 | public static XModuleResources createInstance(String path, XResources origRes) { 32 | if (path == null) 33 | throw new IllegalArgumentException("path must not be null"); 34 | 35 | AssetManager assets = new AssetManager(); 36 | assets.addAssetPath(path); 37 | 38 | XModuleResources res; 39 | if (origRes != null) 40 | res = new XModuleResources(assets, origRes.getDisplayMetrics(), origRes.getConfiguration()); 41 | else 42 | res = new XModuleResources(assets, null, null); 43 | 44 | AndroidAppHelper.addActiveResource(path, res); 45 | return res; 46 | } 47 | 48 | /** 49 | * Creates an {@link XResForwarder} instance that forwards requests to {@code id} in this resource. 50 | */ 51 | public XResForwarder fwd(int id) { 52 | return new XResForwarder(this, id); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/android/content/res/XResForwarder.java: -------------------------------------------------------------------------------- 1 | package android.content.res; 2 | 3 | /** 4 | * Instances of this class can be used for {@link XResources#setReplacement(String, String, String, Object)} 5 | * and its variants. They forward the resource request to a different {@link android.content.res.Resources} 6 | * instance with a possibly different ID. 7 | * 8 | *

Usually, instances aren't created directly but via {@link XModuleResources#fwd}. 9 | */ 10 | public class XResForwarder { 11 | private final Resources res; 12 | private final int id; 13 | 14 | /** 15 | * Creates a new instance. 16 | * 17 | * @param res The target {@link android.content.res.Resources} instance to forward requests to. 18 | * @param id The target resource ID. 19 | */ 20 | public XResForwarder(Resources res, int id) { 21 | this.res = res; 22 | this.id = id; 23 | } 24 | 25 | /** Returns the target {@link android.content.res.Resources} instance. */ 26 | public Resources getResources() { 27 | return res; 28 | } 29 | 30 | /** Returns the target resource ID. */ 31 | public int getId() { 32 | return id; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/android/content/res/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Contains classes that are required for replacing resources. 3 | */ 4 | package android.content.res; 5 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/DexCreator.java: -------------------------------------------------------------------------------- 1 | package de.robv.android.xposed; 2 | 3 | import android.os.Environment; 4 | 5 | import java.io.ByteArrayOutputStream; 6 | import java.io.File; 7 | import java.io.FileInputStream; 8 | import java.io.FileOutputStream; 9 | import java.io.IOException; 10 | import java.io.OutputStream; 11 | import java.security.DigestException; 12 | import java.security.MessageDigest; 13 | import java.security.NoSuchAlgorithmException; 14 | import java.util.zip.Adler32; 15 | 16 | import static de.robv.android.xposed.XposedHelpers.inputStreamToByteArray; 17 | 18 | /** 19 | * Helper class which can create a very simple .dex file, containing only a class definition 20 | * with a super class (no methods, fields, ...). 21 | */ 22 | /*package*/ class DexCreator { 23 | public static File DALVIK_CACHE = new File(Environment.getDataDirectory(), "dalvik-cache"); 24 | 25 | /** Returns the default dex file name for the class. */ 26 | public static File getDefaultFile(String childClz) { 27 | return new File(DALVIK_CACHE, "xposed_" + childClz.substring(childClz.lastIndexOf('.') + 1) + ".dex"); 28 | } 29 | 30 | /** 31 | * Creates (or returns) the path to a dex file which defines the superclass of {@clz} as extending 32 | * {@code realSuperClz}, which by itself must extend {@code topClz}. 33 | */ 34 | public static File ensure(String clz, Class realSuperClz, Class topClz) throws IOException { 35 | if (!topClz.isAssignableFrom(realSuperClz)) { 36 | throw new ClassCastException("Cannot initialize " + clz + " because " + realSuperClz + " does not extend " + topClz); 37 | } 38 | 39 | try { 40 | return ensure("xposed.dummy." + clz + "SuperClass", realSuperClz); 41 | } catch (IOException e) { 42 | throw new IOException("Failed to create a superclass for " + clz, e); 43 | } 44 | } 45 | 46 | /** Like {@link #ensure(File, String, String)}, just for the default dex file name. */ 47 | public static File ensure(String childClz, Class superClz) throws IOException { 48 | return ensure(getDefaultFile(childClz), childClz, superClz.getName()); 49 | } 50 | 51 | /** 52 | * Makes sure that the given file is a simple dex file containing the given classes. 53 | * Creates the file if that's not the case. 54 | */ 55 | public static File ensure(File file, String childClz, String superClz) throws IOException { 56 | // First check if a valid file exists. 57 | try { 58 | byte[] dex = inputStreamToByteArray(new FileInputStream(file)); 59 | if (matches(dex, childClz, superClz)) { 60 | return file; 61 | } else { 62 | file.delete(); 63 | } 64 | } catch (IOException e) { 65 | file.delete(); 66 | } 67 | 68 | // If not, create a new dex file. 69 | byte[] dex = create(childClz, superClz); 70 | FileOutputStream fos = new FileOutputStream(file); 71 | fos.write(dex); 72 | fos.close(); 73 | return file; 74 | } 75 | 76 | /** 77 | * Checks whether the Dex file fits to the class names. 78 | * Assumes that the file has been created with this class. 79 | */ 80 | public static boolean matches(byte[] dex, String childClz, String superClz) throws IOException { 81 | boolean childFirst = childClz.compareTo(superClz) < 0; 82 | byte[] childBytes = stringToBytes("L" + childClz.replace('.', '/') + ";"); 83 | byte[] superBytes = stringToBytes("L" + superClz.replace('.', '/') + ";"); 84 | 85 | int pos = 0xa0; 86 | if (pos + childBytes.length + superBytes.length >= dex.length) { 87 | return false; 88 | } 89 | 90 | for (byte b : childFirst ? childBytes : superBytes) { 91 | if (dex[pos++] != b) { 92 | return false; 93 | } 94 | } 95 | 96 | for (byte b : childFirst ? superBytes: childBytes) { 97 | if (dex[pos++] != b) { 98 | return false; 99 | } 100 | } 101 | 102 | return true; 103 | } 104 | 105 | /** Creates the byte array for the dex file. */ 106 | public static byte[] create(String childClz, String superClz) throws IOException { 107 | boolean childFirst = childClz.compareTo(superClz) < 0; 108 | byte[] childBytes = stringToBytes("L" + childClz.replace('.', '/') + ";"); 109 | byte[] superBytes = stringToBytes("L" + superClz.replace('.', '/') + ";"); 110 | int stringsSize = childBytes.length + superBytes.length; 111 | int padding = -stringsSize & 3; 112 | stringsSize += padding; 113 | 114 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 115 | 116 | // header 117 | out.write("dex\n035\0".getBytes()); // magic 118 | out.write(new byte[24]); // placeholder for checksum and signature 119 | writeInt(out, 0xfc + stringsSize); // file size 120 | writeInt(out, 0x70); // header size 121 | writeInt(out, 0x12345678); // endian constant 122 | writeInt(out, 0); // link size 123 | writeInt(out, 0); // link offset 124 | writeInt(out, 0xa4 + stringsSize); // map offset 125 | writeInt(out, 2); // strings count 126 | writeInt(out, 0x70); // strings offset 127 | writeInt(out, 2); // types count 128 | writeInt(out, 0x78); // types offset 129 | writeInt(out, 0); // prototypes count 130 | writeInt(out, 0); // prototypes offset 131 | writeInt(out, 0); // fields count 132 | writeInt(out, 0); // fields offset 133 | writeInt(out, 0); // methods count 134 | writeInt(out, 0); // methods offset 135 | writeInt(out, 1); // classes count 136 | writeInt(out, 0x80); // classes offset 137 | writeInt(out, 0x5c + stringsSize); // data size 138 | writeInt(out, 0xa0); // data offset 139 | 140 | // string map 141 | writeInt(out, 0xa0); 142 | writeInt(out, 0xa0 + (childFirst ? childBytes.length : superBytes.length)); 143 | 144 | // types 145 | writeInt(out, 0); // first type = first string 146 | writeInt(out, 1); // second type = second string 147 | 148 | // class definitions 149 | writeInt(out, childFirst ? 0 : 1); // class to define = child type 150 | writeInt(out, 1); // access flags = public 151 | writeInt(out, childFirst ? 1 : 0); // super class = super type 152 | writeInt(out, 0); // no interface 153 | writeInt(out, -1); // no source file 154 | writeInt(out, 0); // no annotations 155 | writeInt(out, 0); // no class data 156 | writeInt(out, 0); // no static values 157 | 158 | // string data 159 | out.write(childFirst ? childBytes : superBytes); 160 | out.write(childFirst ? superBytes : childBytes); 161 | out.write(new byte[padding]); 162 | 163 | // annotations 164 | writeInt(out, 0); // no items 165 | 166 | // map 167 | writeInt(out, 7); // items count 168 | writeMapItem(out, 0, 1, 0); // header 169 | writeMapItem(out, 1, 2, 0x70); // strings 170 | writeMapItem(out, 2, 2, 0x78); // types 171 | writeMapItem(out, 6, 1, 0x80); // classes 172 | writeMapItem(out, 0x2002, 2, 0xa0); // string data 173 | writeMapItem(out, 0x1003, 1, 0xa0 + stringsSize); // annotations 174 | writeMapItem(out, 0x1000, 1, 0xa4 + stringsSize); // map list 175 | 176 | byte[] buf = out.toByteArray(); 177 | updateSignature(buf); 178 | updateChecksum(buf); 179 | return buf; 180 | } 181 | 182 | private static void updateSignature(byte[] dex) { 183 | // Update SHA-1 signature 184 | try { 185 | MessageDigest md = MessageDigest.getInstance("SHA-1"); 186 | md.update(dex, 32, dex.length - 32); 187 | md.digest(dex, 12, 20); 188 | } catch (NoSuchAlgorithmException | DigestException e) { 189 | throw new RuntimeException(e); 190 | } 191 | } 192 | 193 | private static void updateChecksum(byte[] dex) { 194 | // Update Adler32 checksum 195 | Adler32 a32 = new Adler32(); 196 | a32.update(dex, 12, dex.length - 12); 197 | int chksum = (int) a32.getValue(); 198 | dex[8] = (byte) (chksum & 0xff); 199 | dex[9] = (byte) (chksum >> 8 & 0xff); 200 | dex[10] = (byte) (chksum >> 16 & 0xff); 201 | dex[11] = (byte) (chksum >> 24 & 0xff); 202 | } 203 | 204 | private static void writeUleb128(OutputStream out, int value) throws IOException { 205 | while (value > 0x7f) { 206 | out.write((value & 0x7f) | 0x80); 207 | value >>>= 7; 208 | } 209 | out.write(value); 210 | } 211 | 212 | private static void writeInt(OutputStream out, int value) throws IOException { 213 | out.write(value); 214 | out.write(value >> 8); 215 | out.write(value >> 16); 216 | out.write(value >> 24); 217 | } 218 | 219 | private static void writeMapItem(OutputStream out, int type, int count, int offset) throws IOException { 220 | writeInt(out, type); 221 | writeInt(out, count); 222 | writeInt(out, offset); 223 | } 224 | 225 | private static byte[] stringToBytes(String s) throws IOException { 226 | ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 227 | writeUleb128(bytes, s.length()); 228 | // This isn't MUTF-8, but should be OK. 229 | bytes.write(s.getBytes("UTF-8")); 230 | bytes.write(0); 231 | return bytes.toByteArray(); 232 | } 233 | 234 | private DexCreator() {} 235 | } 236 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/IXposedHookCmdInit.java: -------------------------------------------------------------------------------- 1 | package de.robv.android.xposed; 2 | 3 | 4 | /** 5 | * Hook the initialization of Java-based command-line tools (like pm). 6 | * 7 | * @hide Xposed no longer hooks command-line tools, therefore this interface shouldn't be 8 | * implemented anymore. 9 | */ 10 | public interface IXposedHookCmdInit extends IXposedMod { 11 | /** 12 | * Called very early during startup of a command-line tool. 13 | * @param startupParam Details about the module itself and the started process. 14 | * @throws Throwable Everything is caught, but it will prevent further initialization of the module. 15 | */ 16 | void initCmdApp(StartupParam startupParam) throws Throwable; 17 | 18 | /** Data holder for {@link #initCmdApp}. */ 19 | final class StartupParam { 20 | /*package*/ StartupParam() {} 21 | 22 | /** The path to the module's APK. */ 23 | public String modulePath; 24 | 25 | /** The class name of the tools that the hook was invoked for. */ 26 | public String startClassName; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/IXposedHookInitPackageResources.java: -------------------------------------------------------------------------------- 1 | package de.robv.android.xposed; 2 | 3 | import android.content.res.XResources; 4 | 5 | import de.robv.android.xposed.callbacks.XC_InitPackageResources; 6 | import de.robv.android.xposed.callbacks.XC_InitPackageResources.InitPackageResourcesParam; 7 | 8 | /** 9 | * Get notified when the resources for an app are initialized. 10 | * In {@link #handleInitPackageResources}, resource replacements can be created. 11 | * 12 | *

This interface should be implemented by the module's main class. Xposed will take care of 13 | * registering it as a callback automatically. 14 | */ 15 | public interface IXposedHookInitPackageResources extends IXposedMod { 16 | /** 17 | * This method is called when resources for an app are being initialized. 18 | * Modules can call special methods of the {@link XResources} class in order to replace resources. 19 | * 20 | * @param resparam Information about the resources. 21 | * @throws Throwable Everything the callback throws is caught and logged. 22 | */ 23 | void handleInitPackageResources(InitPackageResourcesParam resparam) throws Throwable; 24 | 25 | /** @hide */ 26 | final class Wrapper extends XC_InitPackageResources { 27 | private final IXposedHookInitPackageResources instance; 28 | public Wrapper(IXposedHookInitPackageResources instance) { 29 | this.instance = instance; 30 | } 31 | @Override 32 | public void handleInitPackageResources(InitPackageResourcesParam resparam) throws Throwable { 33 | instance.handleInitPackageResources(resparam); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/IXposedHookLoadPackage.java: -------------------------------------------------------------------------------- 1 | package de.robv.android.xposed; 2 | 3 | import android.app.Application; 4 | 5 | import de.robv.android.xposed.callbacks.XC_LoadPackage; 6 | import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam; 7 | 8 | /** 9 | * Get notified when an app ("Android package") is loaded. 10 | * This is especially useful to hook some app-specific methods. 11 | * 12 | *

This interface should be implemented by the module's main class. Xposed will take care of 13 | * registering it as a callback automatically. 14 | */ 15 | public interface IXposedHookLoadPackage extends IXposedMod { 16 | /** 17 | * This method is called when an app is loaded. It's called very early, even before 18 | * {@link Application#onCreate} is called. 19 | * Modules can set up their app-specific hooks here. 20 | * 21 | * @param lpparam Information about the app. 22 | * @throws Throwable Everything the callback throws is caught and logged. 23 | */ 24 | void handleLoadPackage(LoadPackageParam lpparam) throws Throwable; 25 | 26 | /** @hide */ 27 | final class Wrapper extends XC_LoadPackage { 28 | private final IXposedHookLoadPackage instance; 29 | public Wrapper(IXposedHookLoadPackage instance) { 30 | this.instance = instance; 31 | } 32 | @Override 33 | public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable { 34 | instance.handleLoadPackage(lpparam); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/IXposedHookZygoteInit.java: -------------------------------------------------------------------------------- 1 | package de.robv.android.xposed; 2 | 3 | /** 4 | * Hook the initialization of Zygote process(es), from which all the apps are forked. 5 | * 6 | *

Implement this interface in your module's main class in order to be notified when Android is 7 | * starting up. In {@link IXposedHookZygoteInit}, you can modify objects and place hooks that should 8 | * be applied for every app. Only the Android framework/system classes are available at that point 9 | * in time. Use {@code null} as class loader for {@link XposedHelpers#findAndHookMethod(String, ClassLoader, String, Object...)} 10 | * and its variants. 11 | * 12 | *

If you want to hook one/multiple specific apps, use {@link IXposedHookLoadPackage} instead. 13 | */ 14 | public interface IXposedHookZygoteInit extends IXposedMod { 15 | /** 16 | * Called very early during startup of Zygote. 17 | * @param startupParam Details about the module itself and the started process. 18 | * @throws Throwable everything is caught, but will prevent further initialization of the module. 19 | */ 20 | void initZygote(StartupParam startupParam) throws Throwable; 21 | 22 | /** Data holder for {@link #initZygote}. */ 23 | final class StartupParam { 24 | /*package*/ StartupParam() {} 25 | 26 | /** The path to the module's APK. */ 27 | public String modulePath; 28 | 29 | /** 30 | * Always {@code true} on 32-bit ROMs. On 64-bit, it's only {@code true} for the primary 31 | * process that starts the system_server. 32 | */ 33 | public boolean startsSystemServer; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/IXposedMod.java: -------------------------------------------------------------------------------- 1 | package de.robv.android.xposed; 2 | 3 | /** Marker interface for Xposed modules. Cannot be implemented directly. */ 4 | /* package */ interface IXposedMod {} 5 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/SELinuxHelper.java: -------------------------------------------------------------------------------- 1 | package de.robv.android.xposed; 2 | 3 | import android.os.SELinux; 4 | 5 | import de.robv.android.xposed.services.BaseService; 6 | import de.robv.android.xposed.services.BinderService; 7 | import de.robv.android.xposed.services.DirectAccessService; 8 | import de.robv.android.xposed.services.ZygoteService; 9 | 10 | /** 11 | * A helper to work with (or without) SELinux, abstracting much of its big complexity. 12 | */ 13 | public final class SELinuxHelper { 14 | private SELinuxHelper() {} 15 | 16 | /** 17 | * Determines whether SELinux is disabled or enabled. 18 | * 19 | * @return A boolean indicating whether SELinux is enabled. 20 | */ 21 | public static boolean isSELinuxEnabled() { 22 | return sIsSELinuxEnabled; 23 | } 24 | 25 | /** 26 | * Determines whether SELinux is permissive or enforcing. 27 | * 28 | * @return A boolean indicating whether SELinux is enforcing. 29 | */ 30 | public static boolean isSELinuxEnforced() { 31 | return sIsSELinuxEnabled && SELinux.isSELinuxEnforced(); 32 | } 33 | 34 | /** 35 | * Gets the security context of the current process. 36 | * 37 | * @return A String representing the security context of the current process. 38 | */ 39 | public static String getContext() { 40 | return sIsSELinuxEnabled ? SELinux.getContext() : null; 41 | } 42 | 43 | /** 44 | * Retrieve the service to be used when accessing files in {@code /data/data/*}. 45 | * 46 | *

IMPORTANT: If you call this from the Zygote process, 47 | * don't re-use the result in different process! 48 | * 49 | * @return An instance of the service. 50 | */ 51 | public static BaseService getAppDataFileService() { 52 | if (sServiceAppDataFile != null) 53 | return sServiceAppDataFile; 54 | throw new UnsupportedOperationException(); 55 | } 56 | 57 | 58 | // ---------------------------------------------------------------------------- 59 | private static boolean sIsSELinuxEnabled = false; 60 | private static BaseService sServiceAppDataFile = null; 61 | 62 | /*package*/ static void initOnce() { 63 | try { 64 | sIsSELinuxEnabled = SELinux.isSELinuxEnabled(); 65 | } catch (NoClassDefFoundError ignored) {} 66 | } 67 | 68 | /*package*/ static void initForProcess(String packageName) { 69 | if (sIsSELinuxEnabled) { 70 | if (packageName == null) { // Zygote 71 | sServiceAppDataFile = new ZygoteService(); 72 | } else if (packageName.equals("android")) { //system_server 73 | sServiceAppDataFile = BinderService.getService(BinderService.TARGET_APP); 74 | } else { // app 75 | sServiceAppDataFile = new DirectAccessService(); 76 | } 77 | } else { 78 | sServiceAppDataFile = new DirectAccessService(); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/XC_MethodHook.java: -------------------------------------------------------------------------------- 1 | package de.robv.android.xposed; 2 | 3 | import java.lang.reflect.Member; 4 | 5 | import de.robv.android.xposed.callbacks.IXUnhook; 6 | import de.robv.android.xposed.callbacks.XCallback; 7 | 8 | /** 9 | * Callback class for method hooks. 10 | * 11 | *

Usually, anonymous subclasses of this class are created which override 12 | * {@link #beforeHookedMethod} and/or {@link #afterHookedMethod}. 13 | */ 14 | public abstract class XC_MethodHook extends XCallback { 15 | /** 16 | * Creates a new callback with default priority. 17 | */ 18 | @SuppressWarnings("deprecation") 19 | public XC_MethodHook() { 20 | super(); 21 | } 22 | 23 | /** 24 | * Creates a new callback with a specific priority. 25 | * 26 | *

Note that {@link #afterHookedMethod} will be called in reversed order, i.e. 27 | * the callback with the highest priority will be called last. This way, the callback has the 28 | * final control over the return value. {@link #beforeHookedMethod} is called as usual, i.e. 29 | * highest priority first. 30 | * 31 | * @param priority See {@link XCallback#priority}. 32 | */ 33 | public XC_MethodHook(int priority) { 34 | super(priority); 35 | } 36 | 37 | /** 38 | * Called before the invocation of the method. 39 | * 40 | *

You can use {@link MethodHookParam#setResult} and {@link MethodHookParam#setThrowable} 41 | * to prevent the original method from being called. 42 | * 43 | *

Note that implementations shouldn't call {@code super(param)}, it's not necessary. 44 | * 45 | * @param param Information about the method call. 46 | * @throws Throwable Everything the callback throws is caught and logged. 47 | */ 48 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {} 49 | 50 | /** 51 | * Called after the invocation of the method. 52 | * 53 | *

You can use {@link MethodHookParam#setResult} and {@link MethodHookParam#setThrowable} 54 | * to modify the return value of the original method. 55 | * 56 | *

Note that implementations shouldn't call {@code super(param)}, it's not necessary. 57 | * 58 | * @param param Information about the method call. 59 | * @throws Throwable Everything the callback throws is caught and logged. 60 | */ 61 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {} 62 | 63 | /** 64 | * Wraps information about the method call and allows to influence it. 65 | */ 66 | public static final class MethodHookParam extends XCallback.Param { 67 | /** @hide */ 68 | @SuppressWarnings("deprecation") 69 | public MethodHookParam() { 70 | super(); 71 | } 72 | 73 | /** The hooked method/constructor. */ 74 | public Member method; 75 | 76 | /** The {@code this} reference for an instance method, or {@code null} for static methods. */ 77 | public Object thisObject; 78 | 79 | /** Arguments to the method call. */ 80 | public Object[] args; 81 | 82 | private Object result = null; 83 | private Throwable throwable = null; 84 | /* package */ boolean returnEarly = false; 85 | 86 | /** Returns the result of the method call. */ 87 | public Object getResult() { 88 | return result; 89 | } 90 | 91 | /** 92 | * Modify the result of the method call. 93 | * 94 | *

If called from {@link #beforeHookedMethod}, it prevents the call to the original method. 95 | */ 96 | public void setResult(Object result) { 97 | this.result = result; 98 | this.throwable = null; 99 | this.returnEarly = true; 100 | } 101 | 102 | /** Returns the {@link Throwable} thrown by the method, or {@code null}. */ 103 | public Throwable getThrowable() { 104 | return throwable; 105 | } 106 | 107 | /** Returns true if an exception was thrown by the method. */ 108 | public boolean hasThrowable() { 109 | return throwable != null; 110 | } 111 | 112 | /** 113 | * Modify the exception thrown of the method call. 114 | * 115 | *

If called from {@link #beforeHookedMethod}, it prevents the call to the original method. 116 | */ 117 | public void setThrowable(Throwable throwable) { 118 | this.throwable = throwable; 119 | this.result = null; 120 | this.returnEarly = true; 121 | } 122 | 123 | /** Returns the result of the method call, or throws the Throwable caused by it. */ 124 | public Object getResultOrThrowable() throws Throwable { 125 | if (throwable != null) 126 | throw throwable; 127 | return result; 128 | } 129 | } 130 | 131 | /** 132 | * An object with which the method/constructor can be unhooked. 133 | */ 134 | public class Unhook implements IXUnhook { 135 | private final Member hookMethod; 136 | 137 | /*package*/ Unhook(Member hookMethod) { 138 | this.hookMethod = hookMethod; 139 | } 140 | 141 | /** 142 | * Returns the method/constructor that has been hooked. 143 | */ 144 | public Member getHookedMethod() { 145 | return hookMethod; 146 | } 147 | 148 | @Override 149 | public XC_MethodHook getCallback() { 150 | return XC_MethodHook.this; 151 | } 152 | 153 | @SuppressWarnings("deprecation") 154 | @Override 155 | public void unhook() { 156 | XposedBridge.unhookMethod(hookMethod, XC_MethodHook.this); 157 | } 158 | 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/XC_MethodReplacement.java: -------------------------------------------------------------------------------- 1 | package de.robv.android.xposed; 2 | 3 | import de.robv.android.xposed.callbacks.XCallback; 4 | 5 | /** 6 | * A special case of {@link XC_MethodHook} which completely replaces the original method. 7 | */ 8 | public abstract class XC_MethodReplacement extends XC_MethodHook { 9 | /** 10 | * Creates a new callback with default priority. 11 | */ 12 | public XC_MethodReplacement() { 13 | super(); 14 | } 15 | 16 | /** 17 | * Creates a new callback with a specific priority. 18 | * 19 | * @param priority See {@link XCallback#priority}. 20 | */ 21 | public XC_MethodReplacement(int priority) { 22 | super(priority); 23 | } 24 | 25 | /** @hide */ 26 | @Override 27 | protected final void beforeHookedMethod(MethodHookParam param) throws Throwable { 28 | try { 29 | Object result = replaceHookedMethod(param); 30 | param.setResult(result); 31 | } catch (Throwable t) { 32 | param.setThrowable(t); 33 | } 34 | } 35 | 36 | /** @hide */ 37 | @Override 38 | @SuppressWarnings("EmptyMethod") 39 | protected final void afterHookedMethod(MethodHookParam param) throws Throwable {} 40 | 41 | /** 42 | * Shortcut for replacing a method completely. Whatever is returned/thrown here is taken 43 | * instead of the result of the original method (which will not be called). 44 | * 45 | *

Note that implementations shouldn't call {@code super(param)}, it's not necessary. 46 | * 47 | * @param param Information about the method call. 48 | * @throws Throwable Anything that is thrown by the callback will be passed on to the original caller. 49 | */ 50 | @SuppressWarnings("UnusedParameters") 51 | protected abstract Object replaceHookedMethod(MethodHookParam param) throws Throwable; 52 | 53 | /** 54 | * Predefined callback that skips the method without replacements. 55 | */ 56 | public static final XC_MethodReplacement DO_NOTHING = new XC_MethodReplacement(PRIORITY_HIGHEST*2) { 57 | @Override 58 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable { 59 | return null; 60 | } 61 | }; 62 | 63 | /** 64 | * Creates a callback which always returns a specific value. 65 | * 66 | * @param result The value that should be returned to callers of the hooked method. 67 | */ 68 | public static XC_MethodReplacement returnConstant(final Object result) { 69 | return returnConstant(PRIORITY_DEFAULT, result); 70 | } 71 | 72 | /** 73 | * Like {@link #returnConstant(Object)}, but allows to specify a priority for the callback. 74 | * 75 | * @param priority See {@link XCallback#priority}. 76 | * @param result The value that should be returned to callers of the hooked method. 77 | */ 78 | public static XC_MethodReplacement returnConstant(int priority, final Object result) { 79 | return new XC_MethodReplacement(priority) { 80 | @Override 81 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable { 82 | return result; 83 | } 84 | }; 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/XSharedPreferences.java: -------------------------------------------------------------------------------- 1 | package de.robv.android.xposed; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.content.Context; 5 | import android.content.SharedPreferences; 6 | import android.os.Environment; 7 | import android.preference.PreferenceManager; 8 | import android.util.Log; 9 | 10 | import com.android.internal.util.XmlUtils; 11 | 12 | import org.xmlpull.v1.XmlPullParserException; 13 | 14 | import java.io.File; 15 | import java.io.FileNotFoundException; 16 | import java.io.IOException; 17 | import java.util.HashMap; 18 | import java.util.Map; 19 | import java.util.Set; 20 | 21 | import de.robv.android.xposed.services.FileResult; 22 | 23 | /** 24 | * This class is basically the same as SharedPreferencesImpl from AOSP, but 25 | * read-only and without listeners support. Instead, it is made to be 26 | * compatible with all ROMs. 27 | */ 28 | public final class XSharedPreferences implements SharedPreferences { 29 | private static final String TAG = "XSharedPreferences"; 30 | private final File mFile; 31 | private final String mFilename; 32 | private Map mMap; 33 | private boolean mLoaded = false; 34 | private long mLastModified; 35 | private long mFileSize; 36 | 37 | /** 38 | * Read settings from the specified file. 39 | * @param prefFile The file to read the preferences from. 40 | */ 41 | public XSharedPreferences(File prefFile) { 42 | mFile = prefFile; 43 | mFilename = mFile.getAbsolutePath(); 44 | startLoadFromDisk(); 45 | } 46 | 47 | /** 48 | * Read settings from the default preferences for a package. 49 | * These preferences are returned by {@link PreferenceManager#getDefaultSharedPreferences}. 50 | * @param packageName The package name. 51 | */ 52 | public XSharedPreferences(String packageName) { 53 | this(packageName, packageName + "_preferences"); 54 | } 55 | 56 | /** 57 | * Read settings from a custom preferences file for a package. 58 | * These preferences are returned by {@link Context#getSharedPreferences(String, int)}. 59 | * @param packageName The package name. 60 | * @param prefFileName The file name without ".xml". 61 | */ 62 | public XSharedPreferences(String packageName, String prefFileName) { 63 | mFile = new File(Environment.getDataDirectory(), "data/" + packageName + "/shared_prefs/" + prefFileName + ".xml"); 64 | mFilename = mFile.getAbsolutePath(); 65 | startLoadFromDisk(); 66 | } 67 | 68 | /** 69 | * Tries to make the preferences file world-readable. 70 | * 71 | *

Warning: This is only meant to work around permission "fix" functions that are part 72 | * of some recoveries. It doesn't replace the need to open preferences with {@code MODE_WORLD_READABLE} 73 | * in the module's UI code. Otherwise, Android will set stricter permissions again during the next save. 74 | * 75 | *

This will only work if executed as root (e.g. {@code initZygote()}) and only if SELinux is disabled. 76 | * 77 | * @return {@code true} in case the file could be made world-readable. 78 | */ 79 | @SuppressLint("SetWorldReadable") 80 | public boolean makeWorldReadable() { 81 | if (!SELinuxHelper.getAppDataFileService().hasDirectFileAccess()) 82 | return false; // It doesn't make much sense to make the file readable if we wouldn't be able to access it anyway. 83 | 84 | if (!mFile.exists()) // Just in case - the file should never be created if it doesn't exist. 85 | return false; 86 | 87 | return mFile.setReadable(true, false); 88 | } 89 | 90 | /** 91 | * Returns the file that is backing these preferences. 92 | * 93 | *

Warning: The file might not be accessible directly. 94 | */ 95 | public File getFile() { 96 | return mFile; 97 | } 98 | 99 | private void startLoadFromDisk() { 100 | synchronized (this) { 101 | mLoaded = false; 102 | } 103 | new Thread("XSharedPreferences-load") { 104 | @Override 105 | public void run() { 106 | synchronized (XSharedPreferences.this) { 107 | loadFromDiskLocked(); 108 | } 109 | } 110 | }.start(); 111 | } 112 | 113 | @SuppressWarnings({ "rawtypes", "unchecked" }) 114 | private void loadFromDiskLocked() { 115 | if (mLoaded) { 116 | return; 117 | } 118 | 119 | Map map = null; 120 | FileResult result = null; 121 | try { 122 | result = SELinuxHelper.getAppDataFileService().getFileInputStream(mFilename, mFileSize, mLastModified); 123 | if (result.stream != null) { 124 | map = XmlUtils.readMapXml(result.stream); 125 | result.stream.close(); 126 | } else { 127 | // The file is unchanged, keep the current values 128 | map = mMap; 129 | } 130 | } catch (XmlPullParserException e) { 131 | Log.w(TAG, "getSharedPreferences", e); 132 | } catch (FileNotFoundException ignored) { 133 | // SharedPreferencesImpl has a canRead() check, so it doesn't log anything in case the file doesn't exist 134 | } catch (IOException e) { 135 | Log.w(TAG, "getSharedPreferences", e); 136 | } finally { 137 | if (result != null && result.stream != null) { 138 | try { 139 | result.stream.close(); 140 | } catch (RuntimeException rethrown) { 141 | throw rethrown; 142 | } catch (Exception ignored) { 143 | } 144 | } 145 | } 146 | 147 | mLoaded = true; 148 | if (map != null) { 149 | mMap = map; 150 | mLastModified = result.mtime; 151 | mFileSize = result.size; 152 | } else { 153 | mMap = new HashMap<>(); 154 | } 155 | notifyAll(); 156 | } 157 | 158 | /** 159 | * Reload the settings from file if they have changed. 160 | * 161 | *

Warning: With enforcing SELinux, this call might be quite expensive. 162 | */ 163 | public synchronized void reload() { 164 | if (hasFileChanged()) 165 | startLoadFromDisk(); 166 | } 167 | 168 | /** 169 | * Check whether the file has changed since the last time it has been loaded. 170 | * 171 | *

Warning: With enforcing SELinux, this call might be quite expensive. 172 | */ 173 | public synchronized boolean hasFileChanged() { 174 | try { 175 | FileResult result = SELinuxHelper.getAppDataFileService().statFile(mFilename); 176 | return mLastModified != result.mtime || mFileSize != result.size; 177 | } catch (FileNotFoundException ignored) { 178 | // SharedPreferencesImpl doesn't log anything in case the file doesn't exist 179 | return true; 180 | } catch (IOException e) { 181 | Log.w(TAG, "hasFileChanged", e); 182 | return true; 183 | } 184 | } 185 | 186 | private void awaitLoadedLocked() { 187 | while (!mLoaded) { 188 | try { 189 | wait(); 190 | } catch (InterruptedException unused) { 191 | } 192 | } 193 | } 194 | 195 | /** @hide */ 196 | @Override 197 | public Map getAll() { 198 | synchronized (this) { 199 | awaitLoadedLocked(); 200 | return new HashMap<>(mMap); 201 | } 202 | } 203 | 204 | /** @hide */ 205 | @Override 206 | public String getString(String key, String defValue) { 207 | synchronized (this) { 208 | awaitLoadedLocked(); 209 | String v = (String)mMap.get(key); 210 | return v != null ? v : defValue; 211 | } 212 | } 213 | 214 | /** @hide */ 215 | @Override 216 | @SuppressWarnings("unchecked") 217 | public Set getStringSet(String key, Set defValues) { 218 | synchronized (this) { 219 | awaitLoadedLocked(); 220 | Set v = (Set) mMap.get(key); 221 | return v != null ? v : defValues; 222 | } 223 | } 224 | 225 | /** @hide */ 226 | @Override 227 | public int getInt(String key, int defValue) { 228 | synchronized (this) { 229 | awaitLoadedLocked(); 230 | Integer v = (Integer)mMap.get(key); 231 | return v != null ? v : defValue; 232 | } 233 | } 234 | 235 | /** @hide */ 236 | @Override 237 | public long getLong(String key, long defValue) { 238 | synchronized (this) { 239 | awaitLoadedLocked(); 240 | Long v = (Long)mMap.get(key); 241 | return v != null ? v : defValue; 242 | } 243 | } 244 | 245 | /** @hide */ 246 | @Override 247 | public float getFloat(String key, float defValue) { 248 | synchronized (this) { 249 | awaitLoadedLocked(); 250 | Float v = (Float)mMap.get(key); 251 | return v != null ? v : defValue; 252 | } 253 | } 254 | 255 | /** @hide */ 256 | @Override 257 | public boolean getBoolean(String key, boolean defValue) { 258 | synchronized (this) { 259 | awaitLoadedLocked(); 260 | Boolean v = (Boolean)mMap.get(key); 261 | return v != null ? v : defValue; 262 | } 263 | } 264 | 265 | /** @hide */ 266 | @Override 267 | public boolean contains(String key) { 268 | synchronized (this) { 269 | awaitLoadedLocked(); 270 | return mMap.containsKey(key); 271 | } 272 | } 273 | 274 | /** @deprecated Not supported by this implementation. */ 275 | @Deprecated 276 | @Override 277 | public Editor edit() { 278 | throw new UnsupportedOperationException("read-only implementation"); 279 | } 280 | 281 | /** @deprecated Not supported by this implementation. */ 282 | @Deprecated 283 | @Override 284 | public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) { 285 | throw new UnsupportedOperationException("listeners are not supported in this implementation"); 286 | } 287 | 288 | /** @deprecated Not supported by this implementation. */ 289 | @Deprecated 290 | @Override 291 | public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) { 292 | throw new UnsupportedOperationException("listeners are not supported in this implementation"); 293 | } 294 | 295 | } 296 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/callbacks/IXUnhook.java: -------------------------------------------------------------------------------- 1 | package de.robv.android.xposed.callbacks; 2 | 3 | import de.robv.android.xposed.IXposedHookZygoteInit; 4 | 5 | /** 6 | * Interface for objects that can be used to remove callbacks. 7 | * 8 | *

Just like hooking methods etc., unhooking applies only to the current process. 9 | * In other process (or when the app is removed from memory and then restarted), the hook will still 10 | * be active. The Zygote process (see {@link IXposedHookZygoteInit}) is an exception, the hook won't 11 | * be inherited by any future processes forked from it in the future. 12 | * 13 | * @param The class of the callback. 14 | */ 15 | public interface IXUnhook { 16 | /** 17 | * Returns the callback that has been registered. 18 | */ 19 | T getCallback(); 20 | 21 | /** 22 | * Removes the callback. 23 | */ 24 | void unhook(); 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/callbacks/XC_InitPackageResources.java: -------------------------------------------------------------------------------- 1 | package de.robv.android.xposed.callbacks; 2 | 3 | import android.content.res.XResources; 4 | 5 | import de.robv.android.xposed.IXposedHookInitPackageResources; 6 | import de.robv.android.xposed.XposedBridge.CopyOnWriteSortedSet; 7 | 8 | /** 9 | * This class is only used for internal purposes, except for the {@link InitPackageResourcesParam} 10 | * subclass. 11 | */ 12 | public abstract class XC_InitPackageResources extends XCallback implements IXposedHookInitPackageResources { 13 | /** 14 | * Creates a new callback with default priority. 15 | * @hide 16 | */ 17 | @SuppressWarnings("deprecation") 18 | public XC_InitPackageResources() { 19 | super(); 20 | } 21 | 22 | /** 23 | * Creates a new callback with a specific priority. 24 | * 25 | * @param priority See {@link XCallback#priority}. 26 | * @hide 27 | */ 28 | public XC_InitPackageResources(int priority) { 29 | super(priority); 30 | } 31 | 32 | /** 33 | * Wraps information about the resources being initialized. 34 | */ 35 | public static final class InitPackageResourcesParam extends XCallback.Param { 36 | /** @hide */ 37 | public InitPackageResourcesParam(CopyOnWriteSortedSet callbacks) { 38 | super(callbacks); 39 | } 40 | 41 | /** The name of the package for which resources are being loaded. */ 42 | public String packageName; 43 | 44 | /** 45 | * Reference to the resources that can be used for calls to 46 | * {@link XResources#setReplacement(String, String, String, Object)}. 47 | */ 48 | public XResources res; 49 | } 50 | 51 | /** @hide */ 52 | @Override 53 | protected void call(Param param) throws Throwable { 54 | if (param instanceof InitPackageResourcesParam) 55 | handleInitPackageResources((InitPackageResourcesParam) param); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/callbacks/XC_LayoutInflated.java: -------------------------------------------------------------------------------- 1 | package de.robv.android.xposed.callbacks; 2 | 3 | import android.content.res.XResources; 4 | import android.content.res.XResources.ResourceNames; 5 | import android.view.View; 6 | 7 | import de.robv.android.xposed.XposedBridge.CopyOnWriteSortedSet; 8 | 9 | /** 10 | * Callback for hooking layouts. Such callbacks can be passed to {@link XResources#hookLayout} 11 | * and its variants. 12 | */ 13 | public abstract class XC_LayoutInflated extends XCallback { 14 | /** 15 | * Creates a new callback with default priority. 16 | */ 17 | @SuppressWarnings("deprecation") 18 | public XC_LayoutInflated() { 19 | super(); 20 | } 21 | 22 | /** 23 | * Creates a new callback with a specific priority. 24 | * 25 | * @param priority See {@link XCallback#priority}. 26 | */ 27 | public XC_LayoutInflated(int priority) { 28 | super(priority); 29 | } 30 | 31 | /** 32 | * Wraps information about the inflated layout. 33 | */ 34 | public static final class LayoutInflatedParam extends XCallback.Param { 35 | /** @hide */ 36 | public LayoutInflatedParam(CopyOnWriteSortedSet callbacks) { 37 | super(callbacks); 38 | } 39 | 40 | /** The view that has been created from the layout. */ 41 | public View view; 42 | 43 | /** Container with the ID and name of the underlying resource. */ 44 | public ResourceNames resNames; 45 | 46 | /** Directory from which the layout was actually loaded (e.g. "layout-sw600dp"). */ 47 | public String variant; 48 | 49 | /** Resources containing the layout. */ 50 | public XResources res; 51 | } 52 | 53 | /** @hide */ 54 | @Override 55 | protected void call(Param param) throws Throwable { 56 | if (param instanceof LayoutInflatedParam) 57 | handleLayoutInflated((LayoutInflatedParam) param); 58 | } 59 | 60 | /** 61 | * This method is called when the hooked layout has been inflated. 62 | * 63 | * @param liparam Information about the layout and the inflated view. 64 | * @throws Throwable Everything the callback throws is caught and logged. 65 | */ 66 | public abstract void handleLayoutInflated(LayoutInflatedParam liparam) throws Throwable; 67 | 68 | /** 69 | * An object with which the callback can be removed. 70 | */ 71 | public class Unhook implements IXUnhook { 72 | private final String resDir; 73 | private final int id; 74 | 75 | /** @hide */ 76 | public Unhook(String resDir, int id) { 77 | this.resDir = resDir; 78 | this.id = id; 79 | } 80 | 81 | /** 82 | * Returns the resource ID of the hooked layout. 83 | */ 84 | public int getId() { 85 | return id; 86 | } 87 | 88 | @Override 89 | public XC_LayoutInflated getCallback() { 90 | return XC_LayoutInflated.this; 91 | } 92 | 93 | @Override 94 | public void unhook() { 95 | XResources.unhookLayout(resDir, id, XC_LayoutInflated.this); 96 | } 97 | 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/callbacks/XC_LoadPackage.java: -------------------------------------------------------------------------------- 1 | package de.robv.android.xposed.callbacks; 2 | 3 | import android.content.pm.ApplicationInfo; 4 | 5 | import de.robv.android.xposed.IXposedHookLoadPackage; 6 | import de.robv.android.xposed.XposedBridge.CopyOnWriteSortedSet; 7 | 8 | /** 9 | * This class is only used for internal purposes, except for the {@link LoadPackageParam} 10 | * subclass. 11 | */ 12 | public abstract class XC_LoadPackage extends XCallback implements IXposedHookLoadPackage { 13 | /** 14 | * Creates a new callback with default priority. 15 | * @hide 16 | */ 17 | @SuppressWarnings("deprecation") 18 | public XC_LoadPackage() { 19 | super(); 20 | } 21 | 22 | /** 23 | * Creates a new callback with a specific priority. 24 | * 25 | * @param priority See {@link XCallback#priority}. 26 | * @hide 27 | */ 28 | public XC_LoadPackage(int priority) { 29 | super(priority); 30 | } 31 | 32 | /** 33 | * Wraps information about the app being loaded. 34 | */ 35 | public static final class LoadPackageParam extends XCallback.Param { 36 | /** @hide */ 37 | public LoadPackageParam(CopyOnWriteSortedSet callbacks) { 38 | super(callbacks); 39 | } 40 | 41 | /** The name of the package being loaded. */ 42 | public String packageName; 43 | 44 | /** The process in which the package is executed. */ 45 | public String processName; 46 | 47 | /** The ClassLoader used for this package. */ 48 | public ClassLoader classLoader; 49 | 50 | /** More information about the application being loaded. */ 51 | public ApplicationInfo appInfo; 52 | 53 | /** Set to {@code true} if this is the first (and main) application for this process. */ 54 | public boolean isFirstApplication; 55 | } 56 | 57 | /** @hide */ 58 | @Override 59 | protected void call(Param param) throws Throwable { 60 | if (param instanceof LoadPackageParam) 61 | handleLoadPackage((LoadPackageParam) param); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/callbacks/XCallback.java: -------------------------------------------------------------------------------- 1 | package de.robv.android.xposed.callbacks; 2 | 3 | import android.os.Bundle; 4 | 5 | import java.io.Serializable; 6 | 7 | import de.robv.android.xposed.XposedBridge; 8 | import de.robv.android.xposed.XposedBridge.CopyOnWriteSortedSet; 9 | 10 | /** 11 | * Base class for Xposed callbacks. 12 | * 13 | * This class only keeps a priority for ordering multiple callbacks. 14 | * The actual (abstract) callback methods are added by subclasses. 15 | */ 16 | public abstract class XCallback implements Comparable { 17 | /** 18 | * Callback priority, higher number means earlier execution. 19 | * 20 | *

This is usually set to {@link #PRIORITY_DEFAULT}. However, in case a certain callback should 21 | * be executed earlier or later a value between {@link #PRIORITY_HIGHEST} and {@link #PRIORITY_LOWEST} 22 | * can be set instead. The values are just for orientation though, Xposed doesn't enforce any 23 | * boundaries on the priority values. 24 | */ 25 | public final int priority; 26 | 27 | /** @deprecated This constructor can't be hidden for technical reasons. Nevertheless, don't use it! */ 28 | @Deprecated 29 | public XCallback() { 30 | this.priority = PRIORITY_DEFAULT; 31 | } 32 | 33 | /** @hide */ 34 | public XCallback(int priority) { 35 | this.priority = priority; 36 | } 37 | 38 | /** 39 | * Base class for Xposed callback parameters. 40 | */ 41 | public static abstract class Param { 42 | /** @hide */ 43 | public final Object[] callbacks; 44 | private Bundle extra; 45 | 46 | /** @deprecated This constructor can't be hidden for technical reasons. Nevertheless, don't use it! */ 47 | @Deprecated 48 | protected Param() { 49 | callbacks = null; 50 | } 51 | 52 | /** @hide */ 53 | protected Param(CopyOnWriteSortedSet callbacks) { 54 | this.callbacks = callbacks.getSnapshot(); 55 | } 56 | 57 | /** 58 | * This can be used to store any data for the scope of the callback. 59 | * 60 | *

Use this instead of instance variables, as it has a clear reference to e.g. each 61 | * separate call to a method, even when the same method is called recursively. 62 | * 63 | * @see #setObjectExtra 64 | * @see #getObjectExtra 65 | */ 66 | public synchronized Bundle getExtra() { 67 | if (extra == null) 68 | extra = new Bundle(); 69 | return extra; 70 | } 71 | 72 | /** 73 | * Returns an object stored with {@link #setObjectExtra}. 74 | */ 75 | public Object getObjectExtra(String key) { 76 | Serializable o = getExtra().getSerializable(key); 77 | if (o instanceof SerializeWrapper) 78 | return ((SerializeWrapper) o).object; 79 | return null; 80 | } 81 | 82 | /** 83 | * Stores any object for the scope of the callback. For data types that support it, use 84 | * the {@link Bundle} returned by {@link #getExtra} instead. 85 | */ 86 | public void setObjectExtra(String key, Object o) { 87 | getExtra().putSerializable(key, new SerializeWrapper(o)); 88 | } 89 | 90 | private static class SerializeWrapper implements Serializable { 91 | private static final long serialVersionUID = 1L; 92 | private final Object object; 93 | public SerializeWrapper(Object o) { 94 | object = o; 95 | } 96 | } 97 | } 98 | 99 | /** @hide */ 100 | public static void callAll(Param param) { 101 | if (param.callbacks == null) 102 | throw new IllegalStateException("This object was not created for use with callAll"); 103 | 104 | for (int i = 0; i < param.callbacks.length; i++) { 105 | try { 106 | ((XCallback) param.callbacks[i]).call(param); 107 | } catch (Throwable t) { XposedBridge.log(t); } 108 | } 109 | } 110 | 111 | /** @hide */ 112 | protected void call(Param param) throws Throwable {} 113 | 114 | /** @hide */ 115 | @Override 116 | public int compareTo(XCallback other) { 117 | if (this == other) 118 | return 0; 119 | 120 | // order descending by priority 121 | if (other.priority != this.priority) 122 | return other.priority - this.priority; 123 | // then randomly 124 | else if (System.identityHashCode(this) < System.identityHashCode(other)) 125 | return -1; 126 | else 127 | return 1; 128 | } 129 | 130 | /** The default priority, see {@link #priority}. */ 131 | public static final int PRIORITY_DEFAULT = 50; 132 | 133 | /** Execute this callback late, see {@link #priority}. */ 134 | public static final int PRIORITY_LOWEST = -10000; 135 | 136 | /** Execute this callback early, see {@link #priority}. */ 137 | public static final int PRIORITY_HIGHEST = 10000; 138 | } 139 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/callbacks/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Contains the base classes for callbacks. 3 | * 4 | *

For historical reasons, {@link de.robv.android.xposed.XC_MethodHook} and 5 | * {@link de.robv.android.xposed.XC_MethodReplacement} are directly in the 6 | * {@code de.robv.android.xposed} package. 7 | */ 8 | package de.robv.android.xposed.callbacks; 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Contains the main classes of the Xposed framework. 3 | */ 4 | package de.robv.android.xposed; 5 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/services/BaseService.java: -------------------------------------------------------------------------------- 1 | package de.robv.android.xposed.services; 2 | 3 | import java.io.ByteArrayInputStream; 4 | import java.io.FileNotFoundException; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | 8 | import de.robv.android.xposed.SELinuxHelper; 9 | 10 | /** 11 | * General definition of a file access service provided by the Xposed framework. 12 | * 13 | *

References to a concrete subclass should generally be retrieved from {@link SELinuxHelper}. 14 | */ 15 | public abstract class BaseService { 16 | /** Flag for {@link #checkFileAccess}: Read access. */ 17 | public static final int R_OK = 4; 18 | /** Flag for {@link #checkFileAccess}: Write access. */ 19 | public static final int W_OK = 2; 20 | /** Flag for {@link #checkFileAccess}: Executable access. */ 21 | public static final int X_OK = 1; 22 | /** Flag for {@link #checkFileAccess}: File/directory exists. */ 23 | public static final int F_OK = 0; 24 | 25 | /** 26 | * Checks whether the services accesses files directly (instead of using IPC). 27 | * 28 | * @return {@code true} in case direct access is possible. 29 | */ 30 | public boolean hasDirectFileAccess() { 31 | return false; 32 | } 33 | 34 | /** 35 | * Check whether a file is accessible. SELinux might enforce stricter checks. 36 | * 37 | * @param filename The absolute path of the file to check. 38 | * @param mode The mode for POSIX's {@code access()} function. 39 | * @return The result of the {@code access()} function. 40 | */ 41 | public abstract boolean checkFileAccess(String filename, int mode); 42 | 43 | /** 44 | * Check whether a file exists. 45 | * 46 | * @param filename The absolute path of the file to check. 47 | * @return The result of the {@code access()} function. 48 | */ 49 | @SuppressWarnings("BooleanMethodIsAlwaysInverted") 50 | public boolean checkFileExists(String filename) { 51 | return checkFileAccess(filename, F_OK); 52 | } 53 | 54 | /** 55 | * Determine the size and modification time of a file. 56 | * 57 | * @param filename The absolute path of the file to check. 58 | * @return A {@link FileResult} object holding the result. 59 | * @throws IOException In case an error occurred while retrieving the information. 60 | */ 61 | public abstract FileResult statFile(String filename) throws IOException; 62 | 63 | /** 64 | * Determine the size time of a file. 65 | * 66 | * @param filename The absolute path of the file to check. 67 | * @return The file size. 68 | * @throws IOException In case an error occurred while retrieving the information. 69 | */ 70 | public long getFileSize(String filename) throws IOException { 71 | return statFile(filename).size; 72 | } 73 | 74 | /** 75 | * Determine the size time of a file. 76 | * 77 | * @param filename The absolute path of the file to check. 78 | * @return The file modification time. 79 | * @throws IOException In case an error occurred while retrieving the information. 80 | */ 81 | public long getFileModificationTime(String filename) throws IOException { 82 | return statFile(filename).mtime; 83 | } 84 | 85 | /** 86 | * Read a file into memory. 87 | * 88 | * @param filename The absolute path of the file to read. 89 | * @return A {@code byte} array with the file content. 90 | * @throws IOException In case an error occurred while reading the file. 91 | */ 92 | public abstract byte[] readFile(String filename) throws IOException; 93 | 94 | /** 95 | * Read a file into memory, but only if it has changed since the last time. 96 | * 97 | * @param filename The absolute path of the file to read. 98 | * @param previousSize File size of last read. 99 | * @param previousTime File modification time of last read. 100 | * @return A {@link FileResult} object holding the result. 101 | *

The {@link FileResult#content} field might be {@code null} if the file 102 | * is unmodified ({@code previousSize} and {@code previousTime} are still valid). 103 | * @throws IOException In case an error occurred while reading the file. 104 | */ 105 | public abstract FileResult readFile(String filename, long previousSize, long previousTime) throws IOException; 106 | 107 | /** 108 | * Read a file into memory, optionally only if it has changed since the last time. 109 | * 110 | * @param filename The absolute path of the file to read. 111 | * @param offset Number of bytes to skip at the beginning of the file. 112 | * @param length Number of bytes to read (0 means read to end of file). 113 | * @param previousSize Optional: File size of last read. 114 | * @param previousTime Optional: File modification time of last read. 115 | * @return A {@link FileResult} object holding the result. 116 | *

The {@link FileResult#content} field might be {@code null} if the file 117 | * is unmodified ({@code previousSize} and {@code previousTime} are still valid). 118 | * @throws IOException In case an error occurred while reading the file. 119 | */ 120 | public abstract FileResult readFile(String filename, int offset, int length, 121 | long previousSize, long previousTime) throws IOException; 122 | 123 | /** 124 | * Get a stream to the file content. 125 | * Depending on the service, it may or may not be read completely into memory. 126 | * 127 | * @param filename The absolute path of the file to read. 128 | * @return An {@link InputStream} to the file content. 129 | * @throws IOException In case an error occurred while reading the file. 130 | */ 131 | public InputStream getFileInputStream(String filename) throws IOException { 132 | return new ByteArrayInputStream(readFile(filename)); 133 | } 134 | 135 | /** 136 | * Get a stream to the file content, but only if it has changed since the last time. 137 | * Depending on the service, it may or may not be read completely into memory. 138 | * 139 | * @param filename The absolute path of the file to read. 140 | * @param previousSize Optional: File size of last read. 141 | * @param previousTime Optional: File modification time of last read. 142 | * @return A {@link FileResult} object holding the result. 143 | *

The {@link FileResult#stream} field might be {@code null} if the file 144 | * is unmodified ({@code previousSize} and {@code previousTime} are still valid). 145 | * @throws IOException In case an error occurred while reading the file. 146 | */ 147 | public FileResult getFileInputStream(String filename, long previousSize, long previousTime) throws IOException { 148 | FileResult result = readFile(filename, previousSize, previousTime); 149 | if (result.content == null) 150 | return result; 151 | return new FileResult(new ByteArrayInputStream(result.content), result.size, result.mtime); 152 | } 153 | 154 | 155 | // ---------------------------------------------------------------------------- 156 | /*package*/ BaseService() {} 157 | 158 | /*package*/ static void ensureAbsolutePath(String filename) { 159 | if (!filename.startsWith("/")) { 160 | throw new IllegalArgumentException("Only absolute filenames are allowed: " + filename); 161 | } 162 | } 163 | 164 | /*package*/ static void throwCommonIOException(int errno, String errorMsg, String filename, String defaultText) throws IOException { 165 | switch (errno) { 166 | case 1: // EPERM 167 | case 13: // EACCES 168 | throw new FileNotFoundException(errorMsg != null ? errorMsg : "Permission denied: " + filename); 169 | case 2: // ENOENT 170 | throw new FileNotFoundException(errorMsg != null ? errorMsg : "No such file or directory: " + filename); 171 | case 12: // ENOMEM 172 | throw new OutOfMemoryError(errorMsg); 173 | case 21: // EISDIR 174 | throw new FileNotFoundException(errorMsg != null ? errorMsg : "Is a directory: " + filename); 175 | default: 176 | throw new IOException(errorMsg != null ? errorMsg : "Error " + errno + defaultText + filename); 177 | } 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/services/BinderService.java: -------------------------------------------------------------------------------- 1 | package de.robv.android.xposed.services; 2 | 3 | import android.os.IBinder; 4 | import android.os.Parcel; 5 | import android.os.RemoteException; 6 | import android.os.ServiceManager; 7 | 8 | import java.io.IOException; 9 | 10 | /** @hide */ 11 | public final class BinderService extends BaseService { 12 | public static final int TARGET_APP = 0; 13 | public static final int TARGET_SYSTEM = 1; 14 | 15 | /** 16 | * Retrieve the binder service running in the specified context. 17 | * @param target Either {@link #TARGET_APP} or {@link #TARGET_SYSTEM}. 18 | * @return A reference to the service. 19 | * @throws IllegalStateException In case the service doesn't exist (should never happen). 20 | */ 21 | public static BinderService getService(int target) { 22 | if (target < 0 || target > sServices.length) { 23 | throw new IllegalArgumentException("Invalid service target " + target); 24 | } 25 | synchronized (sServices) { 26 | if (sServices[target] == null) { 27 | sServices[target] = new BinderService(target); 28 | } 29 | return sServices[target]; 30 | } 31 | } 32 | 33 | @Override 34 | public boolean checkFileAccess(String filename, int mode) { 35 | ensureAbsolutePath(filename); 36 | 37 | Parcel data = Parcel.obtain(); 38 | Parcel reply = Parcel.obtain(); 39 | data.writeInterfaceToken(INTERFACE_TOKEN); 40 | data.writeString(filename); 41 | data.writeInt(mode); 42 | 43 | try { 44 | mRemote.transact(ACCESS_FILE_TRANSACTION, data, reply, 0); 45 | } catch (RemoteException e) { 46 | data.recycle(); 47 | reply.recycle(); 48 | return false; 49 | } 50 | 51 | reply.readException(); 52 | int result = reply.readInt(); 53 | reply.recycle(); 54 | data.recycle(); 55 | return result == 0; 56 | } 57 | 58 | @Override 59 | public FileResult statFile(String filename) throws IOException { 60 | ensureAbsolutePath(filename); 61 | 62 | Parcel data = Parcel.obtain(); 63 | Parcel reply = Parcel.obtain(); 64 | data.writeInterfaceToken(INTERFACE_TOKEN); 65 | data.writeString(filename); 66 | 67 | try { 68 | mRemote.transact(STAT_FILE_TRANSACTION, data, reply, 0); 69 | } catch (RemoteException e) { 70 | data.recycle(); 71 | reply.recycle(); 72 | throw new IOException(e); 73 | } 74 | 75 | reply.readException(); 76 | int errno = reply.readInt(); 77 | if (errno != 0) 78 | throwCommonIOException(errno, null, filename, " while retrieving attributes for "); 79 | 80 | long size = reply.readLong(); 81 | long time = reply.readLong(); 82 | reply.recycle(); 83 | data.recycle(); 84 | return new FileResult(size, time); 85 | } 86 | 87 | @Override 88 | public byte[] readFile(String filename) throws IOException { 89 | return readFile(filename, 0, 0, 0, 0).content; 90 | } 91 | 92 | @Override 93 | public FileResult readFile(String filename, long previousSize, long previousTime) throws IOException { 94 | return readFile(filename, 0, 0, previousSize, previousTime); 95 | } 96 | 97 | @Override 98 | public FileResult readFile(String filename, int offset, int length, 99 | long previousSize, long previousTime) throws IOException { 100 | ensureAbsolutePath(filename); 101 | 102 | Parcel data = Parcel.obtain(); 103 | Parcel reply = Parcel.obtain(); 104 | data.writeInterfaceToken(INTERFACE_TOKEN); 105 | data.writeString(filename); 106 | data.writeInt(offset); 107 | data.writeInt(length); 108 | data.writeLong(previousSize); 109 | data.writeLong(previousTime); 110 | 111 | try { 112 | mRemote.transact(READ_FILE_TRANSACTION, data, reply, 0); 113 | } catch (RemoteException e) { 114 | data.recycle(); 115 | reply.recycle(); 116 | throw new IOException(e); 117 | } 118 | 119 | reply.readException(); 120 | int errno = reply.readInt(); 121 | String errorMsg = reply.readString(); 122 | long size = reply.readLong(); 123 | long time = reply.readLong(); 124 | byte[] content = reply.createByteArray(); 125 | reply.recycle(); 126 | data.recycle(); 127 | 128 | switch (errno) { 129 | case 0: 130 | return new FileResult(content, size, time); 131 | case 22: // EINVAL 132 | if (errorMsg != null) { 133 | IllegalArgumentException iae = new IllegalArgumentException(errorMsg); 134 | if (offset == 0 && length == 0) 135 | throw new IOException(iae); 136 | else 137 | throw iae; 138 | } else { 139 | throw new IllegalArgumentException("Offset " + offset + " / Length " + length 140 | + " is out of range for " + filename + " with size " + size); 141 | } 142 | default: 143 | throwCommonIOException(errno, errorMsg, filename, " while reading "); 144 | throw new IllegalStateException(); // not reached 145 | } 146 | } 147 | 148 | 149 | // ---------------------------------------------------------------------------- 150 | private static final String INTERFACE_TOKEN = "de.robv.android.xposed.IXposedService"; 151 | 152 | private static final int ACCESS_FILE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 2; 153 | private static final int STAT_FILE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 3; 154 | private static final int READ_FILE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 4; 155 | 156 | private static final String[] SERVICE_NAMES = { "user.xposed.app", "user.xposed.system" }; 157 | private static final BinderService[] sServices = new BinderService[2]; 158 | private final IBinder mRemote; 159 | 160 | private BinderService(int target) { 161 | IBinder binder = ServiceManager.getService(SERVICE_NAMES[target]); 162 | if (binder == null) 163 | throw new IllegalStateException("Service " + SERVICE_NAMES[target] + " does not exist"); 164 | this.mRemote = binder; 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/services/DirectAccessService.java: -------------------------------------------------------------------------------- 1 | package de.robv.android.xposed.services; 2 | 3 | import java.io.BufferedInputStream; 4 | import java.io.File; 5 | import java.io.FileInputStream; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | 9 | /** @hide */ 10 | public final class DirectAccessService extends BaseService { 11 | @Override 12 | public boolean hasDirectFileAccess() { 13 | return true; 14 | } 15 | 16 | @SuppressWarnings("RedundantIfStatement") 17 | @Override 18 | public boolean checkFileAccess(String filename, int mode) { 19 | File file = new File(filename); 20 | if (mode == F_OK && !file.exists()) return false; 21 | if ((mode & R_OK) != 0 && !file.canRead()) return false; 22 | if ((mode & W_OK) != 0 && !file.canWrite()) return false; 23 | if ((mode & X_OK) != 0 && !file.canExecute()) return false; 24 | return true; 25 | } 26 | 27 | @Override 28 | public boolean checkFileExists(String filename) { 29 | return new File(filename).exists(); 30 | } 31 | 32 | @Override 33 | public FileResult statFile(String filename) throws IOException { 34 | File file = new File(filename); 35 | return new FileResult(file.length(), file.lastModified()); 36 | } 37 | 38 | @Override 39 | public byte[] readFile(String filename) throws IOException { 40 | File file = new File(filename); 41 | byte content[] = new byte[(int)file.length()]; 42 | FileInputStream fis = new FileInputStream(file); 43 | fis.read(content); 44 | fis.close(); 45 | return content; 46 | } 47 | 48 | @Override 49 | public FileResult readFile(String filename, long previousSize, long previousTime) throws IOException { 50 | File file = new File(filename); 51 | long size = file.length(); 52 | long time = file.lastModified(); 53 | if (previousSize == size && previousTime == time) 54 | return new FileResult(size, time); 55 | return new FileResult(readFile(filename), size, time); 56 | } 57 | 58 | @Override 59 | public FileResult readFile(String filename, int offset, int length, long previousSize, long previousTime) throws IOException { 60 | File file = new File(filename); 61 | long size = file.length(); 62 | long time = file.lastModified(); 63 | if (previousSize == size && previousTime == time) 64 | return new FileResult(size, time); 65 | 66 | // Shortcut for the simple case 67 | if (offset <= 0 && length <= 0) 68 | return new FileResult(readFile(filename), size, time); 69 | 70 | // Check range 71 | if (offset > 0 && offset >= size) { 72 | throw new IllegalArgumentException("Offset " + offset + " is out of range for " + filename); 73 | } else if (offset < 0) { 74 | offset = 0; 75 | } 76 | 77 | if (length > 0 && (offset + length) > size) { 78 | throw new IllegalArgumentException("Length " + length + " is out of range for " + filename); 79 | } else if (length <= 0) { 80 | length = (int) (size - offset); 81 | } 82 | 83 | byte content[] = new byte[length]; 84 | FileInputStream fis = new FileInputStream(file); 85 | fis.skip(offset); 86 | fis.read(content); 87 | fis.close(); 88 | return new FileResult(content, size, time); 89 | } 90 | 91 | /** 92 | * {@inheritDoc} 93 | *

This implementation returns a BufferedInputStream instead of loading the file into memory. 94 | */ 95 | @Override 96 | public InputStream getFileInputStream(String filename) throws IOException { 97 | return new BufferedInputStream(new FileInputStream(filename), 16*1024); 98 | } 99 | 100 | /** 101 | * {@inheritDoc} 102 | *

This implementation returns a BufferedInputStream instead of loading the file into memory. 103 | */ 104 | @Override 105 | public FileResult getFileInputStream(String filename, long previousSize, long previousTime) throws IOException { 106 | File file = new File(filename); 107 | long size = file.length(); 108 | long time = file.lastModified(); 109 | if (previousSize == size && previousTime == time) 110 | return new FileResult(size, time); 111 | return new FileResult(new BufferedInputStream(new FileInputStream(filename), 16*1024), size, time); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/services/FileResult.java: -------------------------------------------------------------------------------- 1 | package de.robv.android.xposed.services; 2 | 3 | import java.io.InputStream; 4 | 5 | /** 6 | * Holder for the result of a {@link BaseService#readFile} or {@link BaseService#statFile} call. 7 | */ 8 | public final class FileResult { 9 | /** File content, might be {@code null} if the file wasn't read. */ 10 | public final byte[] content; 11 | /** File input stream, might be {@code null} if the file wasn't read. */ 12 | public final InputStream stream; 13 | /** File size. */ 14 | public final long size; 15 | /** File last modification time. */ 16 | public final long mtime; 17 | 18 | /*package*/ FileResult(long size, long mtime) { 19 | this.content = null; 20 | this.stream = null; 21 | this.size = size; 22 | this.mtime = mtime; 23 | } 24 | 25 | /*package*/ FileResult(byte[] content, long size, long mtime) { 26 | this.content = content; 27 | this.stream = null; 28 | this.size = size; 29 | this.mtime = mtime; 30 | } 31 | 32 | /*package*/ FileResult(InputStream stream, long size, long mtime) { 33 | this.content = null; 34 | this.stream = stream; 35 | this.size = size; 36 | this.mtime = mtime; 37 | } 38 | 39 | /** @hide */ 40 | @Override 41 | public String toString() { 42 | StringBuilder sb = new StringBuilder("{"); 43 | if (content != null) { 44 | sb.append("content.length: "); 45 | sb.append(content.length); 46 | sb.append(", "); 47 | } 48 | if (stream != null) { 49 | sb.append("stream: "); 50 | sb.append(stream.toString()); 51 | sb.append(", "); 52 | } 53 | sb.append("size: "); 54 | sb.append(size); 55 | sb.append(", mtime: "); 56 | sb.append(mtime); 57 | sb.append("}"); 58 | return sb.toString(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/services/ZygoteService.java: -------------------------------------------------------------------------------- 1 | package de.robv.android.xposed.services; 2 | 3 | import java.io.IOException; 4 | import java.util.Arrays; 5 | 6 | /** @hide */ 7 | @SuppressWarnings("JniMissingFunction") 8 | public final class ZygoteService extends BaseService { 9 | @Override 10 | public native boolean checkFileAccess(String filename, int mode); 11 | 12 | @Override 13 | public native FileResult statFile(String filename) throws IOException; 14 | 15 | @Override 16 | public native byte[] readFile(String filename) throws IOException; 17 | 18 | @Override 19 | // Just for completeness, we don't expect this to be called often in Zygote. 20 | public FileResult readFile(String filename, long previousSize, long previousTime) throws IOException { 21 | FileResult stat = statFile(filename); 22 | if (previousSize == stat.size && previousTime == stat.mtime) 23 | return stat; 24 | return new FileResult(readFile(filename), stat.size, stat.mtime); 25 | } 26 | 27 | @Override 28 | // Just for completeness, we don't expect this to be called often in Zygote. 29 | public FileResult readFile(String filename, int offset, int length, long previousSize, long previousTime) throws IOException { 30 | FileResult stat = statFile(filename); 31 | if (previousSize == stat.size && previousTime == stat.mtime) 32 | return stat; 33 | 34 | // Shortcut for the simple case 35 | if (offset <= 0 && length <= 0) 36 | return new FileResult(readFile(filename), stat.size, stat.mtime); 37 | 38 | // Check range 39 | if (offset > 0 && offset >= stat.size) { 40 | throw new IllegalArgumentException("offset " + offset + " >= size " + stat.size + " for " + filename); 41 | } else if (offset < 0) { 42 | offset = 0; 43 | } 44 | 45 | if (length > 0 && (offset + length) > stat.size) { 46 | throw new IllegalArgumentException("offset " + offset + " + length " + length + " > size " + stat.size + " for " + filename); 47 | } else if (length <= 0) { 48 | length = (int) (stat.size - offset); 49 | } 50 | 51 | byte[] content = readFile(filename); 52 | return new FileResult(Arrays.copyOfRange(content, offset, offset + length), stat.size, stat.mtime); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/de/robv/android/xposed/services/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Contains file access services provided by the Xposed framework. 3 | */ 4 | package de.robv.android.xposed.services; 5 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | jcenter() 4 | } 5 | dependencies { 6 | classpath 'com.android.tools.build:gradle:2.2.2' 7 | } 8 | } 9 | 10 | allprojects { 11 | repositories { 12 | jcenter() 13 | } 14 | } 15 | 16 | task clean(type: Delete) { 17 | delete rootProject.buildDir 18 | } 19 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rovo89/XposedBridge/a535c02ed9dfd53683cc0274d9f95bcb6ffb9f79/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.2-all.zip 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn ( ) { 37 | echo "$*" 38 | } 39 | 40 | die ( ) { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | for s in "${@}" ; do 159 | s=\"$s\" 160 | APP_ARGS=$APP_ARGS" "$s 161 | done 162 | 163 | # Collect all arguments for the java command, following the shell quoting and substitution rules 164 | eval set -- "$DEFAULT_JVM_OPTS" "$JAVA_OPTS" "$GRADLE_OPTS" "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 165 | 166 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 167 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 168 | cd "$(dirname "$0")" 169 | fi 170 | 171 | exec "$JAVACMD" "$@" 172 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /hiddenapistubs/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /hiddenapistubs/build.gradle: -------------------------------------------------------------------------------- 1 | import com.android.builder.core.BuilderConstants 2 | 3 | apply plugin: 'com.android.library' 4 | 5 | android { 6 | // Only build the release variant 7 | variantFilter { variant -> 8 | if (variant.buildType.name != BuilderConstants.RELEASE) { 9 | variant.ignore = true 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /hiddenapistubs/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /hiddenapistubs/src/main/java/android/app/ActivityThread.java: -------------------------------------------------------------------------------- 1 | package android.app; 2 | 3 | import android.content.pm.ApplicationInfo; 4 | import android.content.res.CompatibilityInfo; 5 | 6 | public final class ActivityThread { 7 | public static ActivityThread currentActivityThread() { 8 | throw new UnsupportedOperationException("STUB"); 9 | } 10 | 11 | public static Application currentApplication() { 12 | throw new UnsupportedOperationException("STUB"); 13 | } 14 | 15 | public static String currentPackageName() { 16 | throw new UnsupportedOperationException("STUB"); 17 | } 18 | 19 | public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai, CompatibilityInfo compatInfo) { 20 | throw new UnsupportedOperationException("STUB"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /hiddenapistubs/src/main/java/android/app/LoadedApk.java: -------------------------------------------------------------------------------- 1 | package android.app; 2 | 3 | import android.content.pm.ApplicationInfo; 4 | 5 | public final class LoadedApk { 6 | public ApplicationInfo getApplicationInfo() { 7 | throw new UnsupportedOperationException("STUB"); 8 | } 9 | 10 | public ClassLoader getClassLoader() { 11 | throw new UnsupportedOperationException("STUB"); 12 | } 13 | 14 | public String getPackageName() { 15 | throw new UnsupportedOperationException("STUB"); 16 | } 17 | 18 | public String getResDir() { 19 | throw new UnsupportedOperationException("STUB"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /hiddenapistubs/src/main/java/android/content/pm/PackageParser.java: -------------------------------------------------------------------------------- 1 | package android.content.pm; 2 | 3 | import java.io.File; 4 | 5 | public class PackageParser { 6 | public static class PackageLite { 7 | public final String packageName = null; 8 | } 9 | 10 | /** Before SDK21 */ 11 | public static PackageLite parsePackageLite(String packageFile, int flags) { 12 | throw new UnsupportedOperationException("STUB"); 13 | } 14 | 15 | /** Since SDK21 */ 16 | public static PackageLite parsePackageLite(File packageFile, int flags) throws PackageParserException { 17 | throw new UnsupportedOperationException("STUB"); 18 | } 19 | 20 | /** Since SDK21 */ 21 | @SuppressWarnings("serial") 22 | public static class PackageParserException extends Exception { 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /hiddenapistubs/src/main/java/android/content/res/AssetManager.java: -------------------------------------------------------------------------------- 1 | package android.content.res; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | 6 | public final class AssetManager { 7 | public final int addAssetPath(String path) { 8 | throw new UnsupportedOperationException("STUB"); 9 | } 10 | 11 | public void close() { 12 | throw new UnsupportedOperationException("STUB"); 13 | } 14 | 15 | public final InputStream open(String fileName) throws IOException { 16 | throw new UnsupportedOperationException("STUB"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /hiddenapistubs/src/main/java/android/content/res/CompatibilityInfo.java: -------------------------------------------------------------------------------- 1 | package android.content.res; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | 6 | public class CompatibilityInfo implements Parcelable { 7 | @Override 8 | public int describeContents() { 9 | throw new UnsupportedOperationException("STUB"); 10 | } 11 | 12 | @Override 13 | public void writeToParcel(Parcel dest, int flags) { 14 | throw new UnsupportedOperationException("STUB"); 15 | } 16 | 17 | public static final Parcelable.Creator CREATOR = null; 18 | } 19 | -------------------------------------------------------------------------------- /hiddenapistubs/src/main/java/android/content/res/Resources.java: -------------------------------------------------------------------------------- 1 | package android.content.res; 2 | 3 | import android.graphics.Movie; 4 | import android.graphics.drawable.Drawable; 5 | import android.util.DisplayMetrics; 6 | import android.util.TypedValue; 7 | 8 | import java.io.InputStream; 9 | 10 | public class Resources { 11 | @SuppressWarnings("serial") 12 | public static class NotFoundException extends RuntimeException { 13 | public NotFoundException() { 14 | } 15 | 16 | public NotFoundException(String name) { 17 | throw new UnsupportedOperationException("STUB"); 18 | } 19 | } 20 | 21 | public final class Theme { 22 | } 23 | 24 | public Resources(AssetManager assets, DisplayMetrics metrics, Configuration config) { 25 | throw new UnsupportedOperationException("STUB"); 26 | } 27 | 28 | public static Resources getSystem() { 29 | throw new UnsupportedOperationException("STUB"); 30 | } 31 | 32 | public XmlResourceParser getAnimation(int id) throws NotFoundException { 33 | throw new UnsupportedOperationException("STUB"); 34 | } 35 | 36 | public final AssetManager getAssets() { 37 | throw new UnsupportedOperationException("STUB"); 38 | } 39 | 40 | public boolean getBoolean(int id) throws NotFoundException { 41 | throw new UnsupportedOperationException("STUB"); 42 | } 43 | 44 | public int getColor(int id) throws NotFoundException { 45 | throw new UnsupportedOperationException("STUB"); 46 | } 47 | 48 | public ColorStateList getColorStateList(int id) throws NotFoundException { 49 | throw new UnsupportedOperationException("STUB"); 50 | } 51 | 52 | public Configuration getConfiguration() { 53 | throw new UnsupportedOperationException("STUB"); 54 | } 55 | 56 | public float getDimension(int id) throws NotFoundException { 57 | throw new UnsupportedOperationException("STUB"); 58 | } 59 | 60 | public int getDimensionPixelOffset(int id) throws NotFoundException { 61 | throw new UnsupportedOperationException("STUB"); 62 | } 63 | 64 | public int getDimensionPixelSize(int id) throws NotFoundException { 65 | throw new UnsupportedOperationException("STUB"); 66 | } 67 | 68 | public DisplayMetrics getDisplayMetrics() { 69 | throw new UnsupportedOperationException("STUB"); 70 | } 71 | 72 | public Drawable getDrawable(int id) throws NotFoundException { 73 | throw new UnsupportedOperationException("STUB"); 74 | } 75 | 76 | /** Since SDK21 */ 77 | public Drawable getDrawable(int id, Theme theme) throws NotFoundException { 78 | throw new UnsupportedOperationException("STUB"); 79 | } 80 | 81 | /** Since SDK21, CM12 */ 82 | public Drawable getDrawable(int id, Theme theme, boolean supportComposedIcons) throws NotFoundException { 83 | throw new UnsupportedOperationException("STUB"); 84 | } 85 | 86 | public Drawable getDrawableForDensity(int id, int density) throws NotFoundException { 87 | throw new UnsupportedOperationException("STUB"); 88 | } 89 | 90 | /** Since SDK21 */ 91 | public Drawable getDrawableForDensity(int id, int density, Theme theme) { 92 | throw new UnsupportedOperationException("STUB"); 93 | } 94 | 95 | /** Since SDK21, CM12 */ 96 | public Drawable getDrawableForDensity(int id, int density, Theme theme, boolean supportComposedIcons) { 97 | throw new UnsupportedOperationException("STUB"); 98 | } 99 | 100 | /** Since SDK21 */ 101 | public float getFloat(int id) { 102 | throw new UnsupportedOperationException("STUB"); 103 | } 104 | 105 | public float getFraction(int id, int base, int pbase) { 106 | throw new UnsupportedOperationException("STUB"); 107 | } 108 | 109 | public int getIdentifier(String name, String defType, String defPackage) { 110 | throw new UnsupportedOperationException("STUB"); 111 | } 112 | 113 | public int[] getIntArray(int id) throws NotFoundException { 114 | throw new UnsupportedOperationException("STUB"); 115 | } 116 | 117 | public int getInteger(int id) throws NotFoundException { 118 | throw new UnsupportedOperationException("STUB"); 119 | } 120 | 121 | public XmlResourceParser getLayout(int id) throws NotFoundException { 122 | throw new UnsupportedOperationException("STUB"); 123 | } 124 | 125 | public Movie getMovie(int id) throws NotFoundException { 126 | throw new UnsupportedOperationException("STUB"); 127 | } 128 | 129 | public String getQuantityString(int id, int quantity) throws NotFoundException { 130 | throw new UnsupportedOperationException("STUB"); 131 | } 132 | 133 | public String getQuantityString(int id, int quantity, Object... formatArgs) { 134 | throw new UnsupportedOperationException("STUB"); 135 | } 136 | 137 | public CharSequence getQuantityText(int id, int quantity) throws NotFoundException { 138 | throw new UnsupportedOperationException("STUB"); 139 | } 140 | 141 | public String getResourceEntryName(int resid) throws NotFoundException { 142 | throw new UnsupportedOperationException("STUB"); 143 | } 144 | 145 | public String getResourceName(int resid) throws NotFoundException { 146 | throw new UnsupportedOperationException("STUB"); 147 | } 148 | 149 | public String getResourcePackageName(int resid) throws NotFoundException { 150 | throw new UnsupportedOperationException("STUB"); 151 | } 152 | 153 | public String getResourceTypeName(int resid) throws NotFoundException { 154 | throw new UnsupportedOperationException("STUB"); 155 | } 156 | 157 | public String getString(int id) throws NotFoundException { 158 | throw new UnsupportedOperationException("STUB"); 159 | } 160 | 161 | public String getString(int id, Object... formatArgs) throws NotFoundException { 162 | throw new UnsupportedOperationException("STUB"); 163 | } 164 | 165 | public String[] getStringArray(int id) throws NotFoundException { 166 | throw new UnsupportedOperationException("STUB"); 167 | } 168 | 169 | public CharSequence getText(int id) throws NotFoundException { 170 | throw new UnsupportedOperationException("STUB"); 171 | } 172 | 173 | public CharSequence getText(int id, CharSequence def) { 174 | throw new UnsupportedOperationException("STUB"); 175 | } 176 | 177 | public CharSequence[] getTextArray(int id) throws NotFoundException { 178 | throw new UnsupportedOperationException("STUB"); 179 | } 180 | 181 | public void getValue(int id, TypedValue outValue, boolean resolveRefs) { 182 | throw new UnsupportedOperationException("STUB"); 183 | } 184 | 185 | public XmlResourceParser getXml(int id) throws NotFoundException { 186 | throw new UnsupportedOperationException("STUB"); 187 | } 188 | 189 | public InputStream openRawResource(int id) throws NotFoundException { 190 | throw new UnsupportedOperationException("STUB"); 191 | } 192 | 193 | public TypedArray obtainTypedArray (int id) { 194 | throw new UnsupportedOperationException("STUB"); 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /hiddenapistubs/src/main/java/android/content/res/TypedArray.java: -------------------------------------------------------------------------------- 1 | package android.content.res; 2 | 3 | import android.graphics.drawable.Drawable; 4 | 5 | public class TypedArray { 6 | /** Only for API stubs creation, DO NOT USE! */ 7 | /*package*/ TypedArray() { 8 | throw new UnsupportedOperationException("STUB"); 9 | } 10 | 11 | protected TypedArray(Resources resources, int[] data, int[] indices, int len) { 12 | throw new UnsupportedOperationException("STUB"); 13 | } 14 | 15 | public boolean getBoolean(int index, boolean defValue) { 16 | throw new UnsupportedOperationException("STUB"); 17 | } 18 | 19 | public int getColor(int index, int defValue) { 20 | throw new UnsupportedOperationException("STUB"); 21 | } 22 | 23 | public ColorStateList getColorStateList(int index) { 24 | throw new UnsupportedOperationException("STUB"); 25 | } 26 | 27 | public float getDimension(int index, float defValue) { 28 | throw new UnsupportedOperationException("STUB"); 29 | } 30 | 31 | public int getDimensionPixelOffset(int index, int defValue) { 32 | throw new UnsupportedOperationException("STUB"); 33 | } 34 | 35 | public int getDimensionPixelSize(int index, int defValue) { 36 | throw new UnsupportedOperationException("STUB"); 37 | } 38 | 39 | public Drawable getDrawable(int index) { 40 | throw new UnsupportedOperationException("STUB"); 41 | } 42 | 43 | public float getFloat(int index, float defValue) { 44 | throw new UnsupportedOperationException("STUB"); 45 | } 46 | 47 | public float getFraction(int index, int base, int pbase, float defValue) { 48 | throw new UnsupportedOperationException("STUB"); 49 | } 50 | 51 | public int getInt(int index, int defValue) { 52 | throw new UnsupportedOperationException("STUB"); 53 | } 54 | 55 | public int getInteger(int index, int defValue) { 56 | throw new UnsupportedOperationException("STUB"); 57 | } 58 | 59 | public int getLayoutDimension(int index, int defValue) { 60 | throw new UnsupportedOperationException("STUB"); 61 | } 62 | 63 | public int getLayoutDimension(int index, String name) { 64 | throw new UnsupportedOperationException("STUB"); 65 | } 66 | 67 | public int getResourceId(int index, int defValue) { 68 | throw new UnsupportedOperationException("STUB"); 69 | } 70 | 71 | public Resources getResources() { 72 | throw new UnsupportedOperationException("STUB"); 73 | } 74 | 75 | public String getString(int index) { 76 | throw new UnsupportedOperationException("STUB"); 77 | } 78 | 79 | public CharSequence getText(int index) { 80 | throw new UnsupportedOperationException("STUB"); 81 | } 82 | 83 | public CharSequence[] getTextArray(int index) { 84 | throw new UnsupportedOperationException("STUB"); 85 | } 86 | 87 | public void recycle() { 88 | throw new UnsupportedOperationException("STUB"); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /hiddenapistubs/src/main/java/android/os/SELinux.java: -------------------------------------------------------------------------------- 1 | package android.os; 2 | 3 | public class SELinux { 4 | public static final String getContext() { 5 | throw new UnsupportedOperationException("STUB"); 6 | } 7 | 8 | public static final boolean isSELinuxEnabled() { 9 | throw new UnsupportedOperationException("STUB"); 10 | } 11 | 12 | public static final boolean isSELinuxEnforced() { 13 | throw new UnsupportedOperationException("STUB"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /hiddenapistubs/src/main/java/android/os/ServiceManager.java: -------------------------------------------------------------------------------- 1 | package android.os; 2 | 3 | public class ServiceManager { 4 | public static IBinder getService(String name) { 5 | throw new UnsupportedOperationException("STUB"); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /hiddenapistubs/src/main/java/com/android/internal/os/RuntimeInit.java: -------------------------------------------------------------------------------- 1 | package com.android.internal.os; 2 | 3 | public class RuntimeInit { 4 | public static final void main(String[] argv) { 5 | throw new UnsupportedOperationException("STUB"); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /hiddenapistubs/src/main/java/com/android/internal/os/ZygoteInit.java: -------------------------------------------------------------------------------- 1 | package com.android.internal.os; 2 | 3 | public class ZygoteInit { 4 | public static void main(String[] argv) { 5 | throw new UnsupportedOperationException("STUB"); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /hiddenapistubs/src/main/java/com/android/internal/util/XmlUtils.java: -------------------------------------------------------------------------------- 1 | package com.android.internal.util; 2 | 3 | import org.xmlpull.v1.XmlPullParserException; 4 | 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.util.HashMap; 8 | 9 | public class XmlUtils { 10 | @SuppressWarnings("rawtypes") 11 | public static final HashMap readMapXml(InputStream in) throws XmlPullParserException, IOException { 12 | throw new UnsupportedOperationException("STUB"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /hiddenapistubs/src/main/java/xposed/dummy/XResourcesSuperClass.java: -------------------------------------------------------------------------------- 1 | package xposed.dummy; 2 | 3 | import android.content.res.Resources; 4 | 5 | /** 6 | * This class is used as super class of XResources. 7 | * 8 | * This implementation isn't included in the .dex file. Instead, it's created on the device. 9 | * Usually, it will extend Resources, but some ROMs use their own Resources subclass. 10 | * In that case, XResourcesSuperClass will extend the ROM's subclass in an attempt to increase 11 | * compatibility. 12 | */ 13 | public class XResourcesSuperClass extends Resources { 14 | /** Dummy, will never be called (objects are transferred to this class only). */ 15 | protected XResourcesSuperClass() { 16 | super(null, null, null); 17 | throw new UnsupportedOperationException(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /hiddenapistubs/src/main/java/xposed/dummy/XTypedArraySuperClass.java: -------------------------------------------------------------------------------- 1 | package xposed.dummy; 2 | 3 | import android.content.res.Resources; 4 | import android.content.res.TypedArray; 5 | 6 | /** 7 | * This class is used as super class of XResources.XTypedArray. 8 | * 9 | * This implementation isn't included in the .dex file. Instead, it's created on the device. 10 | * Usually, it will extend TypedArray, but some ROMs use their own TypedArray subclass. 11 | * In that case, XTypedArraySuperClass will extend the ROM's subclass in an attempt to increase 12 | * compatibility. 13 | */ 14 | public class XTypedArraySuperClass extends TypedArray { 15 | /** Dummy, will never be called (objects are transferred to this class only). */ 16 | protected XTypedArraySuperClass(Resources resources, int[] data, int[] indices, int len) { 17 | super(null, null, null, 0); 18 | throw new UnsupportedOperationException(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':hiddenapistubs' 2 | --------------------------------------------------------------------------------