diff --git a/smtshell/.idea/gradle.xml b/smtshell/.idea/gradle.xml
index a2d7c21..eae4899 100644
--- a/smtshell/.idea/gradle.xml
+++ b/smtshell/.idea/gradle.xml
@@ -11,6 +11,7 @@
+
diff --git a/smtshell/app/build.gradle b/smtshell/app/build.gradle
index e421938..65bacf7 100644
--- a/smtshell/app/build.gradle
+++ b/smtshell/app/build.gradle
@@ -31,6 +31,7 @@ android {
dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.appcompat:appcompat:1.6.1'
+ compileOnly project(':hidden-api-stub')
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
diff --git a/smtshell/hidden-api-stub/.gitignore b/smtshell/hidden-api-stub/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/smtshell/hidden-api-stub/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/smtshell/hidden-api-stub/build.gradle b/smtshell/hidden-api-stub/build.gradle
new file mode 100644
index 0000000..bfc3a8a
--- /dev/null
+++ b/smtshell/hidden-api-stub/build.gradle
@@ -0,0 +1,4 @@
+apply plugin: 'java-library'
+
+sourceCompatibility = "1.7"
+targetCompatibility = "1.7"
\ No newline at end of file
diff --git a/smtshell/hidden-api-stub/src/main/java/android/annotation/NonNull.java b/smtshell/hidden-api-stub/src/main/java/android/annotation/NonNull.java
new file mode 100644
index 0000000..ef6d55a
--- /dev/null
+++ b/smtshell/hidden-api-stub/src/main/java/android/annotation/NonNull.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that a parameter, field or method return value can never be null.
+ *
+ * This is a marker annotation and it has no specific attributes.
+ *
+ * @paramDoc This value must never be {@code null}.
+ * @returnDoc This value will never be {@code null}.
+ * @hide
+ */
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface NonNull {
+}
\ No newline at end of file
diff --git a/smtshell/hidden-api-stub/src/main/java/android/annotation/Nullable.java b/smtshell/hidden-api-stub/src/main/java/android/annotation/Nullable.java
new file mode 100644
index 0000000..daea2b8
--- /dev/null
+++ b/smtshell/hidden-api-stub/src/main/java/android/annotation/Nullable.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that a parameter, field or method return value can be null.
+ *
+ * When decorating a method call parameter, this denotes that the parameter can
+ * legitimately be null and the method will gracefully deal with it. Typically
+ * used on optional parameters.
+ *
+ * When decorating a method, this denotes the method might legitimately return
+ * null.
+ *
+ * This is a marker annotation and it has no specific attributes.
+ *
+ * @paramDoc This value may be {@code null}.
+ * @returnDoc This value may be {@code null}.
+ */
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface Nullable {
+}
diff --git a/smtshell/hidden-api-stub/src/main/java/android/content/IIntentReceiver.java b/smtshell/hidden-api-stub/src/main/java/android/content/IIntentReceiver.java
new file mode 100644
index 0000000..f2f9509
--- /dev/null
+++ b/smtshell/hidden-api-stub/src/main/java/android/content/IIntentReceiver.java
@@ -0,0 +1,15 @@
+package android.content;
+
+import android.os.Binder;
+import android.os.Bundle;
+
+public interface IIntentReceiver {
+
+ void performReceive(Intent intent, int resultCode, String data, Bundle extras,
+ boolean ordered, boolean sticky, int sendingUser)
+ throws android.os.RemoteException;
+
+ abstract class Stub extends Binder implements IIntentReceiver {
+
+ }
+}
diff --git a/smtshell/hidden-api-stub/src/main/java/android/content/IIntentSender.java b/smtshell/hidden-api-stub/src/main/java/android/content/IIntentSender.java
new file mode 100644
index 0000000..842d8a7
--- /dev/null
+++ b/smtshell/hidden-api-stub/src/main/java/android/content/IIntentSender.java
@@ -0,0 +1,34 @@
+package android.content;
+
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.IInterface;
+
+import androidx.annotation.RequiresApi;
+
+public interface IIntentSender extends IInterface {
+
+ int send(int code, Intent intent, String resolvedType,
+ IIntentReceiver finishedReceiver, String requiredPermission, Bundle options);
+
+ @RequiresApi(26)
+ void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
+ IIntentReceiver finishedReceiver, String requiredPermission, Bundle options);
+
+ abstract class Stub extends Binder implements IIntentSender {
+
+ public Stub() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public android.os.IBinder asBinder() {
+ throw new UnsupportedOperationException();
+ }
+
+ public static IIntentSender asInterface(IBinder binder) {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/smtshell/hidden-api-stub/src/main/java/android/content/Intent.java b/smtshell/hidden-api-stub/src/main/java/android/content/Intent.java
new file mode 100644
index 0000000..82e7bc3
--- /dev/null
+++ b/smtshell/hidden-api-stub/src/main/java/android/content/Intent.java
@@ -0,0 +1,5 @@
+package android.content;
+
+public class Intent {
+
+}
diff --git a/smtshell/hidden-api-stub/src/main/java/android/content/IntentSender.java b/smtshell/hidden-api-stub/src/main/java/android/content/IntentSender.java
new file mode 100644
index 0000000..1279e06
--- /dev/null
+++ b/smtshell/hidden-api-stub/src/main/java/android/content/IntentSender.java
@@ -0,0 +1,4 @@
+package android.content;
+
+public class IntentSender {
+}
diff --git a/smtshell/hidden-api-stub/src/main/java/android/content/pm/BaseParceledListSlice.java b/smtshell/hidden-api-stub/src/main/java/android/content/pm/BaseParceledListSlice.java
new file mode 100644
index 0000000..d9af8b5
--- /dev/null
+++ b/smtshell/hidden-api-stub/src/main/java/android/content/pm/BaseParceledListSlice.java
@@ -0,0 +1,10 @@
+package android.content.pm;
+
+import java.util.List;
+
+abstract class BaseParceledListSlice {
+
+ public List getList() {
+ throw new RuntimeException("STUB");
+ }
+}
diff --git a/smtshell/hidden-api-stub/src/main/java/android/content/pm/IPackageInstaller.java b/smtshell/hidden-api-stub/src/main/java/android/content/pm/IPackageInstaller.java
new file mode 100644
index 0000000..6fa1a2d
--- /dev/null
+++ b/smtshell/hidden-api-stub/src/main/java/android/content/pm/IPackageInstaller.java
@@ -0,0 +1,25 @@
+package android.content.pm;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.RemoteException;
+
+public interface IPackageInstaller extends IInterface {
+
+ void abandonSession(int sessionId)
+ throws RemoteException;
+
+ IPackageInstallerSession openSession(int sessionId)
+ throws RemoteException;
+
+ ParceledListSlice getMySessions(String installerPackageName, int userId)
+ throws RemoteException;
+
+ abstract class Stub extends Binder implements IPackageInstaller {
+
+ public static IPackageInstaller asInterface(IBinder binder) {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/smtshell/hidden-api-stub/src/main/java/android/content/pm/IPackageInstallerSession.java b/smtshell/hidden-api-stub/src/main/java/android/content/pm/IPackageInstallerSession.java
new file mode 100644
index 0000000..8c93458
--- /dev/null
+++ b/smtshell/hidden-api-stub/src/main/java/android/content/pm/IPackageInstallerSession.java
@@ -0,0 +1,15 @@
+package android.content.pm;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.IInterface;
+
+public interface IPackageInstallerSession extends IInterface {
+
+ abstract class Stub extends Binder implements IPackageInstallerSession {
+
+ public static IPackageInstallerSession asInterface(IBinder binder) {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/smtshell/hidden-api-stub/src/main/java/android/content/pm/IPackageManager.java b/smtshell/hidden-api-stub/src/main/java/android/content/pm/IPackageManager.java
new file mode 100644
index 0000000..6e4b532
--- /dev/null
+++ b/smtshell/hidden-api-stub/src/main/java/android/content/pm/IPackageManager.java
@@ -0,0 +1,21 @@
+package android.content.pm;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.RemoteException;
+
+import androidx.annotation.RequiresApi;
+
+public interface IPackageManager extends IInterface {
+
+ IPackageInstaller getPackageInstaller()
+ throws RemoteException;
+
+ abstract class Stub extends Binder implements IPackageManager {
+
+ public static IPackageManager asInterface(IBinder obj) {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/smtshell/hidden-api-stub/src/main/java/android/content/pm/PackageInstaller.java b/smtshell/hidden-api-stub/src/main/java/android/content/pm/PackageInstaller.java
new file mode 100644
index 0000000..8ae4d03
--- /dev/null
+++ b/smtshell/hidden-api-stub/src/main/java/android/content/pm/PackageInstaller.java
@@ -0,0 +1,12 @@
+package android.content.pm;
+
+public class PackageInstaller {
+
+ public static class SessionParams {
+
+ }
+
+ public static class SessionInfo {
+
+ }
+}
diff --git a/smtshell/hidden-api-stub/src/main/java/android/content/pm/ParceledListSlice.java b/smtshell/hidden-api-stub/src/main/java/android/content/pm/ParceledListSlice.java
new file mode 100644
index 0000000..927754c
--- /dev/null
+++ b/smtshell/hidden-api-stub/src/main/java/android/content/pm/ParceledListSlice.java
@@ -0,0 +1,4 @@
+package android.content.pm;
+
+public class ParceledListSlice extends BaseParceledListSlice {
+}
diff --git a/smtshell/hidden-api-stub/src/main/java/android/content/pm/UserInfo.java b/smtshell/hidden-api-stub/src/main/java/android/content/pm/UserInfo.java
new file mode 100644
index 0000000..fbe2162
--- /dev/null
+++ b/smtshell/hidden-api-stub/src/main/java/android/content/pm/UserInfo.java
@@ -0,0 +1,6 @@
+package android.content.pm;
+
+public class UserInfo {
+
+ public int id;
+}
diff --git a/smtshell/hidden-api-stub/src/main/java/android/os/Binder.java b/smtshell/hidden-api-stub/src/main/java/android/os/Binder.java
new file mode 100644
index 0000000..49c8716
--- /dev/null
+++ b/smtshell/hidden-api-stub/src/main/java/android/os/Binder.java
@@ -0,0 +1,58 @@
+package android.os;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.io.FileDescriptor;
+
+public class Binder implements IBinder {
+
+ @Override
+ public boolean transact(int code, @NonNull Parcel data, Parcel reply, int flags) {
+ throw new RuntimeException("STUB");
+ }
+
+ @Override
+ public String getInterfaceDescriptor() {
+ throw new RuntimeException("STUB");
+ }
+
+ public boolean pingBinder() {
+ throw new RuntimeException("STUB");
+ }
+
+ @Override
+ public boolean isBinderAlive() {
+ throw new RuntimeException("STUB");
+ }
+
+ @Override
+ public IInterface queryLocalInterface(@NonNull String descriptor) {
+ throw new RuntimeException("STUB");
+ }
+
+ @Override
+ public void dump(@NonNull FileDescriptor fd, String[] args) {
+ throw new RuntimeException("STUB");
+ }
+
+ @Override
+ public void dumpAsync(@NonNull FileDescriptor fd, String[] args) {
+ throw new RuntimeException("STUB");
+ }
+
+ @Override
+ public void linkToDeath(@NonNull DeathRecipient recipient, int flags) {
+ throw new RuntimeException("STUB");
+ }
+
+ @Override
+ public boolean unlinkToDeath(@NonNull DeathRecipient recipient, int flags) {
+ throw new RuntimeException("STUB");
+ }
+
+ protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply,
+ int flags) throws RemoteException {
+ throw new RuntimeException("STUB");
+ }
+}
diff --git a/smtshell/hidden-api-stub/src/main/java/android/os/Bundle.java b/smtshell/hidden-api-stub/src/main/java/android/os/Bundle.java
new file mode 100644
index 0000000..49ff9ee
--- /dev/null
+++ b/smtshell/hidden-api-stub/src/main/java/android/os/Bundle.java
@@ -0,0 +1,4 @@
+package android.os;
+
+public class Bundle {
+}
diff --git a/smtshell/hidden-api-stub/src/main/java/android/os/IBinder.java b/smtshell/hidden-api-stub/src/main/java/android/os/IBinder.java
new file mode 100644
index 0000000..81ad36c
--- /dev/null
+++ b/smtshell/hidden-api-stub/src/main/java/android/os/IBinder.java
@@ -0,0 +1,33 @@
+package android.os;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.io.FileDescriptor;
+
+public interface IBinder {
+
+ boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags);
+
+ @Nullable
+ String getInterfaceDescriptor();
+
+ boolean pingBinder();
+
+ boolean isBinderAlive();
+
+ @Nullable
+ IInterface queryLocalInterface(@NonNull String descriptor);
+
+ void dump(@NonNull FileDescriptor fd, @Nullable String[] args);
+
+ void dumpAsync(@NonNull FileDescriptor fd, @Nullable String[] args);
+
+ void linkToDeath(@NonNull DeathRecipient recipient, int flags);
+
+ boolean unlinkToDeath(@NonNull DeathRecipient recipient, int flags);
+
+ interface DeathRecipient {
+ void binderDied();
+ }
+}
diff --git a/smtshell/hidden-api-stub/src/main/java/android/os/IInterface.java b/smtshell/hidden-api-stub/src/main/java/android/os/IInterface.java
new file mode 100644
index 0000000..997e330
--- /dev/null
+++ b/smtshell/hidden-api-stub/src/main/java/android/os/IInterface.java
@@ -0,0 +1,6 @@
+package android.os;
+
+public interface IInterface {
+
+ IBinder asBinder();
+}
diff --git a/smtshell/hidden-api-stub/src/main/java/android/os/IUserManager.java b/smtshell/hidden-api-stub/src/main/java/android/os/IUserManager.java
new file mode 100644
index 0000000..fcedfb1
--- /dev/null
+++ b/smtshell/hidden-api-stub/src/main/java/android/os/IUserManager.java
@@ -0,0 +1,28 @@
+package android.os;
+
+import android.content.pm.UserInfo;
+
+import androidx.annotation.RequiresApi;
+
+import java.util.List;
+
+public interface IUserManager extends IInterface {
+
+ @RequiresApi(26)
+ boolean isUserUnlocked(int userId)
+ throws RemoteException;
+
+ List getUsers(boolean excludeDying)
+ throws RemoteException;
+
+ @RequiresApi(30)
+ List getUsers(boolean excludePartial, boolean excludeDying, boolean excludePreCreated)
+ throws RemoteException;
+
+ abstract class Stub extends Binder implements IUserManager {
+
+ public static IUserManager asInterface(IBinder obj) {
+ throw new RuntimeException("STUB");
+ }
+ }
+}
diff --git a/smtshell/hidden-api-stub/src/main/java/android/os/Parcel.java b/smtshell/hidden-api-stub/src/main/java/android/os/Parcel.java
new file mode 100644
index 0000000..f506a63
--- /dev/null
+++ b/smtshell/hidden-api-stub/src/main/java/android/os/Parcel.java
@@ -0,0 +1,4 @@
+package android.os;
+
+public class Parcel {
+}
diff --git a/smtshell/hidden-api-stub/src/main/java/android/os/RemoteException.java b/smtshell/hidden-api-stub/src/main/java/android/os/RemoteException.java
new file mode 100644
index 0000000..9b24d72
--- /dev/null
+++ b/smtshell/hidden-api-stub/src/main/java/android/os/RemoteException.java
@@ -0,0 +1,8 @@
+package android.os;
+
+public class RemoteException extends Exception {
+
+ public RemoteException(String message) {
+ throw new RuntimeException("STUB");
+ }
+}
diff --git a/smtshell/hidden-api-stub/src/main/java/androidx/annotation/IntRange.java b/smtshell/hidden-api-stub/src/main/java/androidx/annotation/IntRange.java
new file mode 100644
index 0000000..80691fd
--- /dev/null
+++ b/smtshell/hidden-api-stub/src/main/java/androidx/annotation/IntRange.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+/**
+ * Denotes that the annotated element should be an int or long in the given range
+ *
+ * Example:
+ *
+ * @IntRange(from=0,to=255)
+ * public int getAlpha() {
+ * ...
+ * }
+ *
+ */
+@Retention(CLASS)
+@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE, ANNOTATION_TYPE})
+public @interface IntRange {
+ /**
+ * Smallest value, inclusive
+ */
+ long from() default Long.MIN_VALUE;
+
+ /**
+ * Largest value, inclusive
+ */
+ long to() default Long.MAX_VALUE;
+}
\ No newline at end of file
diff --git a/smtshell/hidden-api-stub/src/main/java/androidx/annotation/RequiresApi.java b/smtshell/hidden-api-stub/src/main/java/androidx/annotation/RequiresApi.java
new file mode 100644
index 0000000..cb1d462
--- /dev/null
+++ b/smtshell/hidden-api-stub/src/main/java/androidx/annotation/RequiresApi.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that the annotated element should only be called on the given API level
+ * or higher.
+ *
+ * This is similar in purpose to the older {@code @TargetApi} annotation, but more
+ * clearly expresses that this is a requirement on the caller, rather than being
+ * used to "suppress" warnings within the method that exceed the {@code minSdkVersion}.
+ */
+@Retention(SOURCE)
+@Target({TYPE, METHOD, CONSTRUCTOR, FIELD})
+public @interface RequiresApi {
+
+ /**
+ * The API level to require. Alias for {@link #api} which allows you to leave out the
+ * {@code api=} part.
+ */
+ @IntRange(from = 1)
+ int value() default 1;
+
+ /**
+ * The API level to require
+ */
+ @IntRange(from = 1)
+ int api() default 1;
+}
\ No newline at end of file
diff --git a/smtshell/settings.gradle b/smtshell/settings.gradle
index e7b4def..48656be 100644
--- a/smtshell/settings.gradle
+++ b/smtshell/settings.gradle
@@ -1 +1 @@
-include ':app'
+include ':app', 'hidden-api-stub'