├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── libs │ ├── edm.jar │ ├── license.jar │ └── rc.jar ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── ic_launcher-web.png │ ├── java │ └── com │ │ └── fusionjack │ │ └── adhell3 │ │ ├── App.java │ │ ├── MainActivity.java │ │ ├── adapter │ │ ├── AdhellPermissionInAppsAdapter.java │ │ ├── AdhellPermissionInfoAdapter.java │ │ ├── AppInfoAdapter.java │ │ ├── AppWhitelistAdapter.java │ │ ├── BlockUrlProviderAdapter.java │ │ ├── ItemClickSupport.java │ │ ├── ProfileAdapter.java │ │ └── ReportBlockedUrlAdapter.java │ │ ├── blocker │ │ ├── ContentBlocker.java │ │ ├── ContentBlocker20.java │ │ ├── ContentBlocker56.java │ │ └── ContentBlocker57.java │ │ ├── dagger │ │ ├── component │ │ │ └── AppComponent.java │ │ ├── module │ │ │ ├── AdminModule.java │ │ │ ├── AppModule.java │ │ │ ├── EnterpriseModule.java │ │ │ └── NetworkModule.java │ │ └── scope │ │ │ └── AdhellApplicationScope.java │ │ ├── db │ │ ├── AppDatabase.java │ │ ├── DateConverter.java │ │ ├── dao │ │ │ ├── AppInfoDao.java │ │ │ ├── AppPermissionDao.java │ │ │ ├── BlockUrlDao.java │ │ │ ├── BlockUrlProviderDao.java │ │ │ ├── DisabledPackageDao.java │ │ │ ├── FirewallWhitelistedPackageDao.java │ │ │ ├── PolicyPackageDao.java │ │ │ ├── ReportBlockedUrlDao.java │ │ │ ├── RestrictedPackageDao.java │ │ │ ├── UserBlockUrlDao.java │ │ │ └── WhiteUrlDao.java │ │ ├── entity │ │ │ ├── AppInfo.java │ │ │ ├── AppPermission.java │ │ │ ├── BlockUrl.java │ │ │ ├── BlockUrlProvider.java │ │ │ ├── DisabledPackage.java │ │ │ ├── FirewallWhitelistedPackage.java │ │ │ ├── PolicyPackage.java │ │ │ ├── ReportBlockedUrl.java │ │ │ ├── RestrictedPackage.java │ │ │ ├── UserBlockUrl.java │ │ │ └── WhiteUrl.java │ │ ├── migration │ │ │ ├── Migration_14_15.java │ │ │ ├── Migration_15_16.java │ │ │ ├── Migration_16_17.java │ │ │ ├── Migration_17_18.java │ │ │ ├── Migration_18_19.java │ │ │ ├── Migration_19_20.java │ │ │ ├── Migration_20_21.java │ │ │ ├── Migration_21_22.java │ │ │ └── Migration_22_23.java │ │ └── repository │ │ │ ├── AppInfoRepository.java │ │ │ ├── BlockUrlProviderRepository.java │ │ │ └── BlockUrlRepository.java │ │ ├── dialogfragment │ │ ├── AdhellNotSupportedDialogFragment.java │ │ ├── AdhellTurnOnDialogFragment.java │ │ ├── DnsChangeDialogFragment.java │ │ └── NoInternetConnectionDialogFragment.java │ │ ├── fragments │ │ ├── AdhellNotSupportedFragment.java │ │ ├── AdhellPermissionInAppsFragment.java │ │ ├── AdhellPermissionInfoFragment.java │ │ ├── AdhellReportsFragment.java │ │ ├── AppListFragment.java │ │ ├── AppSettingsFragment.java │ │ ├── BlockCustomUrlFragment.java │ │ ├── BlockedUrlSettingFragment.java │ │ ├── BlockerFragment.java │ │ ├── CustomBlockUrlProviderFragment.java │ │ ├── LoadAppAsyncTask.java │ │ ├── MobileRestricterFragment.java │ │ ├── PackageDisablerFragment.java │ │ ├── RefreshAppAsyncTask.java │ │ ├── ShowBlockUrlFragment.java │ │ └── WhitelistFragment.java │ │ ├── model │ │ ├── AdhellPermissionInfo.java │ │ ├── AndroidDeviceForm.java │ │ └── BillingModel.java │ │ ├── net │ │ ├── AdhellInfoResponse.java │ │ └── CustomResponse.java │ │ ├── receiver │ │ ├── ApplicationsListChangedReceiver.java │ │ └── CustomDeviceAdminReceiver.java │ │ ├── utils │ │ ├── AdhellAppIntegrity.java │ │ ├── AppsListDBInitializer.java │ │ ├── BlockUrlPatternsMatch.java │ │ ├── BlockUrlUtils.java │ │ ├── DeviceAdminInteractor.java │ │ └── LogUtils.java │ │ └── viewmodel │ │ ├── AdhellWhitelistAppsViewModel.java │ │ ├── AppPermissionsViewModel.java │ │ ├── BlockUrlProvidersViewModel.java │ │ ├── ProfileViewModel.java │ │ └── SharedAppPermissionViewModel.java │ └── res │ ├── animator │ ├── enter_from_left.xml │ ├── enter_from_right.xml │ ├── exit_to_left.xml │ └── exit_to_right.xml │ ├── drawable-hdpi │ ├── ic_check_box_black_24dp.png │ ├── ic_check_box_outline_blank_black_24dp.png │ ├── ic_delete_black_24dp.png │ ├── ic_home_black_24dp.png │ ├── ic_lock_black_24dp.png │ ├── ic_question_answer.png │ ├── ic_settings_white_24dp.png │ ├── ic_signal_cellular_no_sim_black_24dp.png │ ├── ic_sort_white_24dp.png │ ├── ic_visibility_off_black_24dp.png │ └── overflow.png │ ├── drawable-mdpi │ ├── ic_check_box_black_24dp.png │ ├── ic_check_box_outline_blank_black_24dp.png │ ├── ic_delete_black_24dp.png │ ├── ic_home_black_24dp.png │ ├── ic_lock_black_24dp.png │ ├── ic_question_answer.png │ ├── ic_settings_white_24dp.png │ ├── ic_signal_cellular_no_sim_black_24dp.png │ ├── ic_sort_white_24dp.png │ ├── ic_visibility_off_black_24dp.png │ └── overflow.png │ ├── drawable-xhdpi │ ├── ic_check_box_black_24dp.png │ ├── ic_check_box_outline_blank_black_24dp.png │ ├── ic_delete_black_24dp.png │ ├── ic_home_black_24dp.png │ ├── ic_lock_black_24dp.png │ ├── ic_question_answer.png │ ├── ic_settings_white_24dp.png │ ├── ic_signal_cellular_no_sim_black_24dp.png │ ├── ic_sort_white_24dp.png │ ├── ic_visibility_off_black_24dp.png │ └── overflow.png │ ├── drawable-xxhdpi │ ├── ic_check_box_black_24dp.png │ ├── ic_check_box_outline_blank_black_24dp.png │ ├── ic_delete_black_24dp.png │ ├── ic_home_black_24dp.png │ ├── ic_lock_black_24dp.png │ ├── ic_question_answer.png │ ├── ic_settings_white_24dp.png │ ├── ic_signal_cellular_no_sim_black_24dp.png │ ├── ic_sort_white_24dp.png │ ├── ic_visibility_off_black_24dp.png │ └── overflow.png │ ├── drawable-xxxhdpi │ ├── ic_check_box_black_24dp.png │ ├── ic_check_box_outline_blank_black_24dp.png │ ├── ic_delete_black_24dp.png │ ├── ic_home_black_24dp.png │ ├── ic_lock_black_24dp.png │ ├── ic_question_answer.png │ ├── ic_settings_white_24dp.png │ ├── ic_signal_cellular_no_sim_black_24dp.png │ ├── ic_sort_white_24dp.png │ ├── ic_visibility_off_black_24dp.png │ └── overflow.png │ ├── drawable │ └── checkbox.xml │ ├── layout │ ├── activity_main.xml │ ├── card_profile.xml │ ├── checkbox.xml │ ├── dialog_dns.xml │ ├── dialog_fragment_adhell_not_supported.xml │ ├── dialog_fragment_no_internet_connection.xml │ ├── dialog_fragment_turn_on_adhell.xml │ ├── fragment_adhell_not_supported.xml │ ├── fragment_adhell_permission_info.xml │ ├── fragment_adhell_reports.xml │ ├── fragment_app_list.xml │ ├── fragment_app_settings.xml │ ├── fragment_app_support.xml │ ├── fragment_blocked_url_settings.xml │ ├── fragment_blocker.xml │ ├── fragment_custom_url_provider.xml │ ├── fragment_manual_url_block.xml │ ├── fragment_mobile_restricter.xml │ ├── fragment_package_disabler.xml │ ├── fragment_permission_in_apps.xml │ ├── fragment_show_blocked_urls.xml │ ├── fragment_white_list.xml │ ├── item_app_list_view.xml │ ├── item_block_url_provider.xml │ ├── item_blocked_url_info.xml │ ├── item_disable_app_list_view.xml │ ├── item_permission_in_app.xml │ └── item_permission_info.xml │ ├── menu │ ├── mobile_restricter_menu.xml │ ├── package_disabler_menu.xml │ ├── profiles_menu.xml │ ├── search_menu.xml │ └── settings.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values-de │ └── strings.xml │ ├── values-es │ └── strings.xml │ ├── values-fr │ └── strings.xml │ ├── values-it │ └── strings.xml │ ├── values-nl │ └── strings.xml │ ├── values-ru │ └── strings.xml │ ├── values-zh-rTW │ └── strings.xml │ ├── values │ ├── colors.xml │ ├── dimens.xml │ ├── ids.xml │ ├── keys.xml │ ├── strings.xml │ └── styles.xml │ └── xml │ ├── bottombar_tabs.xml │ └── enterprise_device_admin.xml ├── build.gradle ├── circle.yml ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── hosts └── hosts.txt └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .idea 10 | *.apk 11 | fabric.properties 12 | app/release -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | gradle.properties 3 | fabric.properties 4 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenCentral() 4 | jcenter() 5 | maven { url 'https://maven.google.com' } 6 | } 7 | } 8 | 9 | apply plugin: 'com.android.application' 10 | 11 | android { 12 | compileSdkVersion 26 13 | 14 | defaultConfig { 15 | applicationId "com." 16 | minSdkVersion 16 17 | targetSdkVersion 26 18 | versionCode 1 19 | versionName "3.0.0" 20 | } 21 | buildTypes { 22 | compileOptions { 23 | sourceCompatibility JavaVersion.VERSION_1_8 24 | targetCompatibility JavaVersion.VERSION_1_8 25 | } 26 | } 27 | 28 | packagingOptions { 29 | exclude 'META-INF/DEPENDENCIES.txt' 30 | exclude 'META-INF/LICENSE.txt' 31 | exclude 'META-INF/NOTICE.txt' 32 | exclude 'META-INF/NOTICE' 33 | exclude 'META-INF/LICENSE' 34 | exclude 'META-INF/DEPENDENCIES' 35 | exclude 'META-INF/notice.txt' 36 | exclude 'META-INF/license.txt' 37 | exclude 'META-INF/dependencies.txt' 38 | exclude 'META-INF/LGPL2.1' 39 | } 40 | } 41 | 42 | dependencies { 43 | implementation fileTree(dir: 'libs', include: ['*.jar']) 44 | 45 | testImplementation 'junit:junit:4.12' 46 | implementation 'com.android.support:appcompat-v7:26.1.0' 47 | implementation 'com.android.support:support-v4:26.1.0' 48 | implementation 'com.android.support:recyclerview-v7:26.1.0' 49 | implementation 'com.android.support:percent:26.1.0' 50 | implementation 'com.android.support:transition:26.1.0' 51 | implementation 'com.android.support:design:26.1.0' 52 | implementation "com.android.support:support-fragment:26.1.0" 53 | implementation 'com.android.support:cardview-v7:26.1.0' 54 | implementation 'com.google.code.gson:gson:2.8.0' 55 | implementation 'com.squareup.okhttp3:okhttp:3.8.1' 56 | 57 | implementation 'io.reactivex.rxjava2:rxandroid:2.0.2' 58 | implementation 'io.reactivex.rxjava2:rxjava:2.1.9' 59 | 60 | implementation 'com.roughike:bottom-bar:2.3.1' 61 | 62 | implementation "android.arch.lifecycle:extensions:1.1.1" 63 | annotationProcessor "android.arch.lifecycle:compiler:1.1.1" 64 | 65 | implementation "android.arch.persistence.room:runtime:1.0.0" 66 | annotationProcessor "android.arch.persistence.room:compiler:1.0.0" 67 | implementation "android.arch.persistence.room:rxjava2:1.0.0" 68 | 69 | implementation "com.google.dagger:dagger:2.15" 70 | annotationProcessor "com.google.dagger:dagger-compiler:2.15" 71 | compileOnly 'javax.annotation:jsr250-api:1.0' 72 | } -------------------------------------------------------------------------------- /app/libs/edm.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/libs/edm.jar -------------------------------------------------------------------------------- /app/libs/license.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/libs/license.jar -------------------------------------------------------------------------------- /app/libs/rc.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/libs/rc.jar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /home/raiym/hdd/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 22 | 23 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 37 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/App.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3; 2 | 3 | 4 | import android.app.Application; 5 | 6 | import com.fusionjack.adhell3.dagger.component.AppComponent; 7 | import com.fusionjack.adhell3.dagger.component.DaggerAppComponent; 8 | import com.fusionjack.adhell3.dagger.module.AppModule; 9 | 10 | public class App extends Application { 11 | private static App instance; 12 | private AppComponent appComponent; 13 | 14 | public static App get() { 15 | return instance; 16 | } 17 | 18 | @Override 19 | public void onCreate() { 20 | super.onCreate(); 21 | instance = this; 22 | appComponent = initDagger(instance); 23 | } 24 | 25 | protected AppComponent initDagger(App application) { 26 | return DaggerAppComponent.builder() 27 | .appModule(new AppModule(application)) 28 | .build(); 29 | } 30 | 31 | 32 | public AppComponent getAppComponent() { 33 | return appComponent; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/adapter/AdhellPermissionInfoAdapter.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.adapter; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.TextView; 9 | 10 | import com.fusionjack.adhell3.R; 11 | import com.fusionjack.adhell3.model.AdhellPermissionInfo; 12 | 13 | import java.util.List; 14 | 15 | public class AdhellPermissionInfoAdapter extends RecyclerView.Adapter { 16 | private Context mContext; 17 | private List mAdhellPermissionInfos; 18 | 19 | public AdhellPermissionInfoAdapter(Context context, List adhellPermissionInfos) { 20 | mContext = context; 21 | mAdhellPermissionInfos = adhellPermissionInfos; 22 | } 23 | 24 | @Override 25 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 26 | Context context = parent.getContext(); 27 | LayoutInflater inflater = LayoutInflater.from(context); 28 | View permissionInfoView = inflater.inflate(R.layout.item_permission_info, parent, false); 29 | return new ViewHolder(permissionInfoView); 30 | } 31 | 32 | @Override 33 | public void onBindViewHolder(ViewHolder holder, int position) { 34 | AdhellPermissionInfo adhellPermissionInfo = mAdhellPermissionInfos.get(position); 35 | holder.permissionLabelTextView.setText(adhellPermissionInfo.label); 36 | holder.permissionNameTextView.setText(adhellPermissionInfo.name); 37 | } 38 | 39 | @Override 40 | public int getItemCount() { 41 | return mAdhellPermissionInfos.size(); 42 | } 43 | 44 | public class ViewHolder extends RecyclerView.ViewHolder { 45 | TextView permissionLabelTextView; 46 | TextView permissionNameTextView; 47 | 48 | ViewHolder(View itemView) { 49 | super(itemView); 50 | permissionLabelTextView = (TextView) itemView.findViewById(R.id.permissionLabelTextView); 51 | permissionNameTextView = (TextView) itemView.findViewById(R.id.permissionNameTextView); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/adapter/AppInfoAdapter.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.adapter; 2 | 3 | import android.content.Context; 4 | import android.content.pm.PackageManager; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.BaseAdapter; 9 | import android.widget.ImageView; 10 | import android.widget.Switch; 11 | import android.widget.TextView; 12 | 13 | import com.fusionjack.adhell3.R; 14 | import com.fusionjack.adhell3.db.entity.AppInfo; 15 | 16 | import java.lang.ref.WeakReference; 17 | import java.util.List; 18 | 19 | public class AppInfoAdapter extends BaseAdapter { 20 | 21 | private List applicationInfoList; 22 | private WeakReference contextReference; 23 | private PackageManager packageManager; 24 | private boolean disabler; 25 | 26 | public AppInfoAdapter(List appInfoList, boolean disabler, Context context, PackageManager packageManager) { 27 | this.applicationInfoList = appInfoList; 28 | this.contextReference = new WeakReference<>(context); 29 | this.packageManager = packageManager; 30 | this.disabler = disabler; 31 | } 32 | 33 | @Override 34 | public int getCount() { 35 | return this.applicationInfoList.size(); 36 | } 37 | 38 | @Override 39 | public AppInfo getItem(int position) { 40 | return this.applicationInfoList.get(position); 41 | } 42 | 43 | @Override 44 | public long getItemId(int position) { 45 | return position; 46 | } 47 | 48 | @Override 49 | public View getView(int position, View convertView, ViewGroup parent) { 50 | ViewHolder holder; 51 | if (convertView == null) { 52 | convertView = LayoutInflater.from(contextReference.get()).inflate(R.layout.item_disable_app_list_view, parent, false); 53 | holder = new ViewHolder(); 54 | holder.nameH = convertView.findViewById(R.id.appName); 55 | holder.packageH = convertView.findViewById(R.id.packName); 56 | holder.switchH = convertView.findViewById(R.id.switchDisable); 57 | holder.imageH = convertView.findViewById(R.id.appIcon); 58 | convertView.setTag(holder); 59 | } else { 60 | holder = (ViewHolder) convertView.getTag(); 61 | } 62 | 63 | AppInfo appInfo = applicationInfoList.get(position); 64 | holder.nameH.setText(appInfo.appName); 65 | holder.packageH.setText(appInfo.packageName); 66 | holder.switchH.setChecked(disabler ? !appInfo.disabled : !appInfo.mobileRestricted); 67 | if (appInfo.system) { 68 | convertView.findViewById(R.id.systemOrNot).setVisibility(View.VISIBLE); 69 | } else { 70 | convertView.findViewById(R.id.systemOrNot).setVisibility(View.GONE); 71 | } 72 | try { 73 | holder.imageH.setImageDrawable(packageManager.getApplicationIcon(appInfo.packageName)); 74 | } catch (PackageManager.NameNotFoundException e) { 75 | e.printStackTrace(); 76 | } 77 | return convertView; 78 | } 79 | 80 | private static class ViewHolder { 81 | TextView nameH; 82 | TextView packageH; 83 | Switch switchH; 84 | ImageView imageH; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/adapter/ItemClickSupport.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.adapter; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.view.View; 5 | 6 | import com.fusionjack.adhell3.R; 7 | 8 | /* 9 | Source: http://www.littlerobots.nl/blog/Handle-Android-RecyclerView-Clicks/ 10 | USAGE: 11 | 12 | ItemClickSupport.addTo(mRecyclerView).setOnItemClickListener(new ItemClickSupport.OnItemClickListener() { 13 | @Override 14 | public void onItemClicked(RecyclerView recyclerView, int position, View v) { 15 | // do it 16 | } 17 | }); 18 | 19 | */ 20 | public class ItemClickSupport { 21 | private final RecyclerView mRecyclerView; 22 | private OnItemClickListener mOnItemClickListener; 23 | private OnItemLongClickListener mOnItemLongClickListener; 24 | private View.OnClickListener mOnClickListener = new View.OnClickListener() { 25 | @Override 26 | public void onClick(View v) { 27 | if (mOnItemClickListener != null) { 28 | RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v); 29 | mOnItemClickListener.onItemClicked(mRecyclerView, holder.getAdapterPosition(), v); 30 | } 31 | } 32 | }; 33 | private View.OnLongClickListener mOnLongClickListener = new View.OnLongClickListener() { 34 | @Override 35 | public boolean onLongClick(View v) { 36 | if (mOnItemLongClickListener != null) { 37 | RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v); 38 | return mOnItemLongClickListener.onItemLongClicked(mRecyclerView, holder.getAdapterPosition(), v); 39 | } 40 | return false; 41 | } 42 | }; 43 | private RecyclerView.OnChildAttachStateChangeListener mAttachListener 44 | = new RecyclerView.OnChildAttachStateChangeListener() { 45 | @Override 46 | public void onChildViewAttachedToWindow(View view) { 47 | if (mOnItemClickListener != null) { 48 | view.setOnClickListener(mOnClickListener); 49 | } 50 | if (mOnItemLongClickListener != null) { 51 | view.setOnLongClickListener(mOnLongClickListener); 52 | } 53 | } 54 | 55 | @Override 56 | public void onChildViewDetachedFromWindow(View view) { 57 | 58 | } 59 | }; 60 | 61 | private ItemClickSupport(RecyclerView recyclerView) { 62 | mRecyclerView = recyclerView; 63 | mRecyclerView.setTag(R.id.item_click_support, this); 64 | mRecyclerView.addOnChildAttachStateChangeListener(mAttachListener); 65 | } 66 | 67 | public static ItemClickSupport addTo(RecyclerView view) { 68 | ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support); 69 | if (support == null) { 70 | support = new ItemClickSupport(view); 71 | } 72 | return support; 73 | } 74 | 75 | public static ItemClickSupport removeFrom(RecyclerView view) { 76 | ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support); 77 | if (support != null) { 78 | support.detach(view); 79 | } 80 | return support; 81 | } 82 | 83 | public ItemClickSupport setOnItemClickListener(OnItemClickListener listener) { 84 | mOnItemClickListener = listener; 85 | return this; 86 | } 87 | 88 | public ItemClickSupport setOnItemLongClickListener(OnItemLongClickListener listener) { 89 | mOnItemLongClickListener = listener; 90 | return this; 91 | } 92 | 93 | private void detach(RecyclerView view) { 94 | view.removeOnChildAttachStateChangeListener(mAttachListener); 95 | view.setTag(R.id.item_click_support, null); 96 | } 97 | 98 | public interface OnItemClickListener { 99 | 100 | void onItemClicked(RecyclerView recyclerView, int position, View v); 101 | } 102 | 103 | public interface OnItemLongClickListener { 104 | 105 | boolean onItemLongClicked(RecyclerView recyclerView, int position, View v); 106 | } 107 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/adapter/ProfileAdapter.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.adapter; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.Switch; 8 | import android.widget.TextView; 9 | 10 | import com.fusionjack.adhell3.R; 11 | import com.fusionjack.adhell3.db.entity.PolicyPackage; 12 | 13 | import java.text.SimpleDateFormat; 14 | import java.util.Date; 15 | import java.util.List; 16 | 17 | public class ProfileAdapter extends RecyclerView.Adapter { 18 | 19 | private List policyPackages; 20 | private Context mContext; 21 | 22 | public ProfileAdapter(Context context, List policyPackages) { 23 | this.mContext = context; 24 | this.policyPackages = policyPackages; 25 | } 26 | 27 | @Override 28 | public ProfileViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 29 | return null; 30 | } 31 | 32 | @Override 33 | public void onBindViewHolder(ProfileViewHolder holder, int position) { 34 | PolicyPackage policyPackage = policyPackages.get(position); 35 | holder.profileNameTextView.setText(policyPackage.name); 36 | holder.profileSwitch.setChecked(policyPackage.active); 37 | Date updatedAt = policyPackage.updatedAt; 38 | SimpleDateFormat dt = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss"); 39 | String lastModifiedText 40 | = mContext.getString(R.string.last_modified).replace("{{lastModified}}", dt.format(updatedAt)); 41 | holder.lastModifiedTextView.setText(lastModifiedText); 42 | String numberOfDisabledPackagesText 43 | = mContext.getString(R.string.number_packages_disabled).replace("{{numberOfDisabledPackages}}", "" + policyPackage.numberOfDisabledPackages); 44 | holder.numberOfDisabledPackagesTextView.setText(numberOfDisabledPackagesText); 45 | String numberOfHostsText 46 | = mContext.getString(R.string.number_of_hosts) 47 | .replace("{{numberOfHosts}}", "" + policyPackage.numberOfHosts); 48 | holder.numberOfHostsTextView.setText(numberOfHostsText); 49 | 50 | String numberOfUserBlockedDomainsText 51 | = mContext.getString(R.string.custom_domains_blocked) 52 | .replace("{{numberOfDomainsBlockedByUser}}", "" + policyPackage.numberOfUserBlockedDomains); 53 | holder.numberOfUserBlockedUrlsTextView.setText(numberOfUserBlockedDomainsText); 54 | String numberOfWhitelistedDomainsText 55 | = mContext.getString(R.string.number_of_domains_whitelisted) 56 | .replace("{{numberOfWhitelistedDomains}}", "" + policyPackage.numberOfUserWhitelistedDomains); 57 | holder.numberOfUserWhitelistUrlsTextView.setText(numberOfWhitelistedDomainsText); 58 | 59 | String numberOfWhitelistedPermissionsText 60 | = mContext.getString(R.string.number_of_permissions_restricted) 61 | .replace("{{numberOfRestrictedPermissions}}", "" + policyPackage.numberOfChangedPermissions); 62 | holder.numberOfRestrictedPermissions.setText(numberOfWhitelistedPermissionsText); 63 | } 64 | 65 | @Override 66 | public int getItemCount() { 67 | return policyPackages.size(); 68 | } 69 | 70 | public class ProfileViewHolder extends RecyclerView.ViewHolder { 71 | TextView profileNameTextView; 72 | Switch profileSwitch; 73 | TextView lastModifiedTextView; 74 | TextView numberOfDisabledPackagesTextView; 75 | TextView numberOfHostsTextView; 76 | TextView numberOfUserBlockedUrlsTextView; 77 | TextView numberOfUserWhitelistUrlsTextView; 78 | TextView numberOfRestrictedPermissions; 79 | 80 | public ProfileViewHolder(View itemView) { 81 | super(itemView); 82 | profileNameTextView = itemView.findViewById(R.id.profileNameTextView); 83 | profileSwitch = itemView.findViewById(R.id.profileSwitch); 84 | lastModifiedTextView = itemView.findViewById(R.id.lastModifiedTextView); 85 | numberOfDisabledPackagesTextView = itemView.findViewById(R.id.numberOfDisabledPackagesTextView); 86 | numberOfHostsTextView = itemView.findViewById(R.id.numberOfHostsTextView); 87 | numberOfUserBlockedUrlsTextView = itemView.findViewById(R.id.numberOfUserBlockedUrlsTextView); 88 | numberOfUserWhitelistUrlsTextView = itemView.findViewById(R.id.numberOfUserWhitelistUrlsTextView); 89 | numberOfRestrictedPermissions = itemView.findViewById(R.id.numberOfRestrictedPermissions); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/adapter/ReportBlockedUrlAdapter.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.adapter; 2 | 3 | import android.content.Context; 4 | import android.content.pm.ApplicationInfo; 5 | import android.content.pm.PackageManager; 6 | import android.graphics.drawable.Drawable; 7 | import android.support.annotation.NonNull; 8 | import android.support.annotation.Nullable; 9 | import android.util.Log; 10 | import android.view.LayoutInflater; 11 | import android.view.View; 12 | import android.view.ViewGroup; 13 | import android.widget.ArrayAdapter; 14 | import android.widget.ImageView; 15 | import android.widget.TextView; 16 | 17 | import com.fusionjack.adhell3.R; 18 | import com.fusionjack.adhell3.db.entity.ReportBlockedUrl; 19 | 20 | import java.text.SimpleDateFormat; 21 | import java.util.List; 22 | 23 | public class ReportBlockedUrlAdapter extends ArrayAdapter { 24 | private static final String TAG = ReportBlockedUrlAdapter.class.getCanonicalName(); 25 | private PackageManager packageManager; 26 | 27 | private static final SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss"); 28 | 29 | public ReportBlockedUrlAdapter(@NonNull Context context, @NonNull List objects) { 30 | super(context, 0, objects); 31 | packageManager = getContext().getPackageManager(); 32 | } 33 | 34 | @NonNull 35 | @Override 36 | public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { 37 | if (convertView == null) { 38 | convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_blocked_url_info, parent, false); 39 | } 40 | ReportBlockedUrl reportBlockedUrl = getItem(position); 41 | if (reportBlockedUrl == null) { 42 | return convertView; 43 | } 44 | 45 | ImageView blockedDomainIconImageView = convertView.findViewById(R.id.blockedDomainIconImageView); 46 | TextView blockedDomainAppNameTextView = convertView.findViewById(R.id.blockedDomainAppNameTextView); 47 | TextView blockedDomainUrlTextView = convertView.findViewById(R.id.blockedDomainUrlTextView); 48 | TextView blockedDomainTimeTextView = convertView.findViewById(R.id.blockedDomainTimeTextView); 49 | 50 | String packageName = reportBlockedUrl.packageName; 51 | Drawable icon = null; 52 | try { 53 | icon = packageManager.getApplicationIcon(packageName); 54 | } catch (PackageManager.NameNotFoundException e) { 55 | Log.e(TAG, "Failed to getAll application icon.", e); 56 | } 57 | 58 | ApplicationInfo ai; 59 | try { 60 | ai = packageManager.getApplicationInfo(packageName, 0); 61 | } catch (final PackageManager.NameNotFoundException e) { 62 | ai = null; 63 | } 64 | String applicationName = (String) (ai != null ? packageManager.getApplicationLabel(ai) : "(unknown)"); 65 | 66 | if (icon != null) { 67 | blockedDomainIconImageView.setImageDrawable(icon); 68 | } 69 | blockedDomainAppNameTextView.setText(applicationName); 70 | blockedDomainUrlTextView.setText(reportBlockedUrl.url); 71 | blockedDomainTimeTextView.setText(dateFormatter.format(reportBlockedUrl.blockDate)); 72 | 73 | return convertView; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/blocker/ContentBlocker.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.blocker; 2 | 3 | public interface ContentBlocker { 4 | 5 | public boolean enableBlocker(); 6 | 7 | public boolean disableBlocker(); 8 | 9 | public boolean isEnabled(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/blocker/ContentBlocker57.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.blocker; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | import android.util.Log; 6 | import android.util.Patterns; 7 | 8 | import com.fusionjack.adhell3.App; 9 | import com.sec.enterprise.AppIdentity; 10 | import com.sec.enterprise.firewall.DomainFilterRule; 11 | import com.sec.enterprise.firewall.Firewall; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | public class ContentBlocker57 implements ContentBlocker { 17 | private static final String TAG = ContentBlocker57.class.getCanonicalName(); 18 | private static ContentBlocker57 mInstance = null; 19 | 20 | private ContentBlocker56 contentBlocker56; 21 | 22 | private ContentBlocker57() { 23 | contentBlocker56 = ContentBlocker56.getInstance(); 24 | } 25 | 26 | private static synchronized ContentBlocker57 getSync() { 27 | if (mInstance == null) { 28 | mInstance = new ContentBlocker57(); 29 | } 30 | return mInstance; 31 | } 32 | 33 | public static ContentBlocker57 getInstance() { 34 | if (mInstance == null) { 35 | mInstance = getSync(); 36 | } 37 | return mInstance; 38 | } 39 | 40 | @Override 41 | public boolean enableBlocker() { 42 | if (contentBlocker56.enableBlocker()) { 43 | SharedPreferences sharedPreferences = App.get().getApplicationContext().getSharedPreferences("dnsAddresses", Context.MODE_PRIVATE); 44 | if (sharedPreferences.contains("dns1") && sharedPreferences.contains("dns2")) { 45 | String dns1 = sharedPreferences.getString("dns1", null); 46 | String dns2 = sharedPreferences.getString("dns2", null); 47 | if (dns1 != null && dns2 != null 48 | && Patterns.IP_ADDRESS.matcher(dns1).matches() 49 | && Patterns.IP_ADDRESS.matcher(dns2).matches()) { 50 | this.setDns(dns1, dns2); 51 | } 52 | Log.d(TAG, "Previous dns addresses has been applied. " + dns1 + " " + dns2); 53 | } 54 | return true; 55 | } 56 | return false; 57 | } 58 | 59 | @Override 60 | public boolean disableBlocker() { 61 | return contentBlocker56.disableBlocker(); 62 | } 63 | 64 | @Override 65 | public boolean isEnabled() { 66 | return contentBlocker56.isEnabled(); 67 | } 68 | 69 | public void setDns(String dns1, String dns2) { 70 | DomainFilterRule domainFilterRule = new DomainFilterRule(new AppIdentity(Firewall.FIREWALL_ALL_PACKAGES, null)); 71 | domainFilterRule.setDns1(dns1); 72 | domainFilterRule.setDns2(dns2); 73 | List rules = new ArrayList<>(); 74 | rules.add(domainFilterRule); 75 | contentBlocker56.mFirewall.addDomainFilterRules(rules); 76 | Log.d(TAG, "DNS1: " + domainFilterRule.getDns1()); 77 | Log.d(TAG, "DNS2: " + domainFilterRule.getDns2()); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/dagger/component/AppComponent.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.dagger.component; 2 | 3 | import com.fusionjack.adhell3.adapter.AdhellPermissionInAppsAdapter; 4 | import com.fusionjack.adhell3.blocker.ContentBlocker20; 5 | import com.fusionjack.adhell3.blocker.ContentBlocker56; 6 | import com.fusionjack.adhell3.dagger.module.AdminModule; 7 | import com.fusionjack.adhell3.dagger.module.AppModule; 8 | import com.fusionjack.adhell3.dagger.module.EnterpriseModule; 9 | import com.fusionjack.adhell3.dagger.module.NetworkModule; 10 | import com.fusionjack.adhell3.dagger.scope.AdhellApplicationScope; 11 | import com.fusionjack.adhell3.fragments.AdhellPermissionInAppsFragment; 12 | import com.fusionjack.adhell3.fragments.AdhellPermissionInfoFragment; 13 | import com.fusionjack.adhell3.fragments.AdhellReportsFragment; 14 | import com.fusionjack.adhell3.fragments.BlockedUrlSettingFragment; 15 | import com.fusionjack.adhell3.fragments.BlockerFragment; 16 | import com.fusionjack.adhell3.fragments.MobileRestricterFragment; 17 | import com.fusionjack.adhell3.fragments.PackageDisablerFragment; 18 | import com.fusionjack.adhell3.utils.AdhellAppIntegrity; 19 | import com.fusionjack.adhell3.utils.AppsListDBInitializer; 20 | import com.fusionjack.adhell3.utils.DeviceAdminInteractor; 21 | import com.fusionjack.adhell3.viewmodel.AdhellWhitelistAppsViewModel; 22 | import com.fusionjack.adhell3.viewmodel.SharedAppPermissionViewModel; 23 | 24 | import dagger.Component; 25 | 26 | @AdhellApplicationScope 27 | @Component(modules = {AppModule.class, AdminModule.class, EnterpriseModule.class, NetworkModule.class}) 28 | public interface AppComponent { 29 | void inject(DeviceAdminInteractor deviceAdminInteractor); 30 | 31 | void inject(ContentBlocker56 contentBlocker56); 32 | 33 | void inject(ContentBlocker20 contentBlocker20); 34 | 35 | void inject(AdhellReportsFragment adhellReportsFragment); 36 | 37 | void inject(BlockedUrlSettingFragment blockedUrlSettingFragment); 38 | 39 | void inject(PackageDisablerFragment packageDisablerFragment); 40 | 41 | void inject(MobileRestricterFragment mobileRestricterFragment); 42 | 43 | void inject(AdhellWhitelistAppsViewModel adhellWhitelistAppsViewModel); 44 | 45 | void inject(SharedAppPermissionViewModel sharedAppPermissionViewModel); 46 | 47 | void inject(AdhellPermissionInAppsAdapter adhellPermissionInAppsAdapter); 48 | 49 | void inject(AppsListDBInitializer appsListDBInitializer); 50 | 51 | void inject(BlockerFragment blockerFragment); 52 | 53 | void inject(AdhellAppIntegrity adhellAppIntegrity); 54 | 55 | void inject(AdhellPermissionInfoFragment adhellPermissionInfoFragment); 56 | 57 | void inject(AdhellPermissionInAppsFragment adhellPermissionInAppsFragment); 58 | 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/dagger/module/AdminModule.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.dagger.module; 2 | 3 | import android.app.admin.DevicePolicyManager; 4 | import android.content.ComponentName; 5 | import android.content.Context; 6 | 7 | import com.fusionjack.adhell3.dagger.scope.AdhellApplicationScope; 8 | import com.fusionjack.adhell3.receiver.CustomDeviceAdminReceiver; 9 | 10 | import dagger.Module; 11 | import dagger.Provides; 12 | 13 | @Module(includes = {AppModule.class}) 14 | public class AdminModule { 15 | @Provides 16 | @AdhellApplicationScope 17 | DevicePolicyManager providesDevicePolicyManager(Context appContext) { 18 | return (DevicePolicyManager) appContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 19 | } 20 | 21 | @Provides 22 | @AdhellApplicationScope 23 | ComponentName providesComponentName(Context appContext) { 24 | return new ComponentName(appContext, CustomDeviceAdminReceiver.class); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/dagger/module/AppModule.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.dagger.module; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import android.content.SharedPreferences; 6 | import android.content.pm.PackageManager; 7 | 8 | import com.fusionjack.adhell3.dagger.scope.AdhellApplicationScope; 9 | import com.fusionjack.adhell3.db.AppDatabase; 10 | 11 | import dagger.Module; 12 | import dagger.Provides; 13 | 14 | @Module 15 | public class AppModule { 16 | 17 | private static final String APP_GENERAL_PREFERENCES = "app_general_preferences"; 18 | 19 | private Application mApplication; 20 | 21 | public AppModule(Application application) { 22 | mApplication = application; 23 | } 24 | 25 | @Provides 26 | @AdhellApplicationScope 27 | Application providesApplication() { 28 | return mApplication; 29 | } 30 | 31 | @Provides 32 | @AdhellApplicationScope 33 | Context providesContext() { 34 | return mApplication.getApplicationContext(); 35 | } 36 | 37 | @Provides 38 | @AdhellApplicationScope 39 | AppDatabase providesAppDatabase() { 40 | return AppDatabase.getAppDatabase(mApplication.getApplicationContext()); 41 | } 42 | 43 | @Provides 44 | @AdhellApplicationScope 45 | PackageManager providesPackageManager() { 46 | return mApplication.getPackageManager(); 47 | } 48 | 49 | @Provides 50 | @AdhellApplicationScope 51 | SharedPreferences providesSharedPreferences(Context context) { 52 | return context.getSharedPreferences(APP_GENERAL_PREFERENCES, Context.MODE_PRIVATE); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/dagger/module/EnterpriseModule.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.dagger.module; 2 | 3 | import android.app.enterprise.ApplicationPermissionControlPolicy; 4 | import android.app.enterprise.ApplicationPolicy; 5 | import android.app.enterprise.EnterpriseDeviceManager; 6 | import android.app.enterprise.FirewallPolicy; 7 | import android.app.enterprise.license.EnterpriseLicenseManager; 8 | import android.content.Context; 9 | import android.support.annotation.Nullable; 10 | import android.util.Log; 11 | 12 | import com.fusionjack.adhell3.dagger.scope.AdhellApplicationScope; 13 | import com.sec.enterprise.firewall.Firewall; 14 | 15 | import dagger.Module; 16 | import dagger.Provides; 17 | 18 | import static android.app.enterprise.EnterpriseDeviceManager.ENTERPRISE_POLICY_SERVICE; 19 | 20 | @Module(includes = {AppModule.class}) 21 | public class EnterpriseModule { 22 | private static final String TAG = EnterpriseModule.class.getCanonicalName(); 23 | 24 | @Nullable 25 | @Provides 26 | @AdhellApplicationScope 27 | EnterpriseLicenseManager providesEnterpriseLicenseManager(Context appContext) { 28 | try { 29 | Log.i(TAG, "Trying to get EnterpriseLicenseManager"); 30 | return EnterpriseLicenseManager.getInstance(appContext); 31 | } catch (Throwable e) { 32 | Log.e(TAG, "Failed to get EnterpriseLicenseManager. So it seems that Knox is not supported on this device", e); 33 | } 34 | return null; 35 | } 36 | 37 | @Nullable 38 | @Provides 39 | @AdhellApplicationScope 40 | EnterpriseDeviceManager providesEnterpriseDeviceManager(Context appContext) { 41 | try { 42 | Log.i(TAG, "Trying to get EnterpriseDeviceManager"); 43 | return (EnterpriseDeviceManager) appContext.getSystemService(ENTERPRISE_POLICY_SERVICE); 44 | } catch (Throwable e) { 45 | Log.w(TAG, "Failed to get EnterpriseDeviceManager", e); 46 | return null; 47 | } 48 | } 49 | 50 | @Nullable 51 | @Provides 52 | @AdhellApplicationScope 53 | ApplicationPolicy providesApplicationPolicy(@Nullable EnterpriseDeviceManager enterpriseDeviceManager) { 54 | if (enterpriseDeviceManager == null) { 55 | return null; 56 | } 57 | return enterpriseDeviceManager.getApplicationPolicy(); 58 | } 59 | 60 | @Nullable 61 | @Provides 62 | @AdhellApplicationScope 63 | ApplicationPermissionControlPolicy providesApplicationPermissionControlPolicy(@Nullable EnterpriseDeviceManager enterpriseDeviceManager) { 64 | if (enterpriseDeviceManager == null) { 65 | Log.w(TAG, "enterpriseDeviceManager is null. Can't get ApplicationPermissionControlPolicy"); 66 | return null; 67 | } 68 | return enterpriseDeviceManager.getApplicationPermissionControlPolicy(); 69 | } 70 | 71 | @Nullable 72 | @Provides 73 | @AdhellApplicationScope 74 | FirewallPolicy providesFirewallPolicy(@Nullable EnterpriseDeviceManager enterpriseDeviceManager) { 75 | if (enterpriseDeviceManager == null) { 76 | Log.w(TAG, "enterpriseDeviceManager is null. Can't get FirewallPolicy"); 77 | return null; 78 | } 79 | try { 80 | Log.i(TAG, "Trying to get FirewallPolicy"); 81 | return enterpriseDeviceManager.getFirewallPolicy(); 82 | } catch (Throwable e) { 83 | Log.e(TAG, "Failed to get firewallPolicy", e); 84 | } 85 | return null; 86 | } 87 | 88 | @Nullable 89 | @Provides 90 | @AdhellApplicationScope 91 | Firewall providesFirewall(@Nullable EnterpriseDeviceManager enterpriseDeviceManager) { 92 | if (enterpriseDeviceManager == null) { 93 | Log.w(TAG, "enterpriseDeviceManager is null. Can't get firewall"); 94 | return null; 95 | } 96 | try { 97 | Log.i(TAG, "Trying to get Firewall"); 98 | return enterpriseDeviceManager.getFirewall(); 99 | } catch (Throwable throwable) { 100 | Log.e(TAG, "Failed to get firewall", throwable); 101 | } 102 | return null; 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/dagger/module/NetworkModule.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.dagger.module; 2 | 3 | import android.util.Log; 4 | 5 | import com.fusionjack.adhell3.dagger.scope.AdhellApplicationScope; 6 | import com.google.gson.Gson; 7 | 8 | import java.util.concurrent.TimeUnit; 9 | 10 | import dagger.Module; 11 | import dagger.Provides; 12 | import okhttp3.OkHttpClient; 13 | 14 | @Module 15 | public class NetworkModule { 16 | 17 | private static final String TAG = NetworkModule.class.getCanonicalName(); 18 | 19 | @Provides 20 | @AdhellApplicationScope 21 | OkHttpClient providesOkHttpClient() { 22 | OkHttpClient okHttpClient = new OkHttpClient.Builder() 23 | .connectTimeout(20, TimeUnit.SECONDS) 24 | .readTimeout(20, TimeUnit.SECONDS) 25 | .writeTimeout(15, TimeUnit.SECONDS) 26 | .build(); 27 | Log.i(TAG, "Providing okHttpClient"); 28 | return okHttpClient; 29 | } 30 | 31 | @Provides 32 | @AdhellApplicationScope 33 | Gson providesGson() { 34 | return new Gson(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/dagger/scope/AdhellApplicationScope.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.dagger.scope; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | import javax.inject.Scope; 7 | 8 | @Scope 9 | @Retention(RetentionPolicy.CLASS) 10 | public @interface AdhellApplicationScope { 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/DateConverter.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db; 2 | 3 | import android.arch.persistence.room.TypeConverter; 4 | 5 | import java.util.Date; 6 | 7 | public class DateConverter { 8 | @TypeConverter 9 | public Date fromTimestamp(Long value) { 10 | return value == null ? null : new Date(value); 11 | } 12 | 13 | @TypeConverter 14 | public Long dateToTimestamp(Date date) { 15 | return date == null ? null : date.getTime(); 16 | } 17 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/dao/AppInfoDao.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.dao; 2 | 3 | import android.arch.lifecycle.LiveData; 4 | import android.arch.persistence.room.Dao; 5 | import android.arch.persistence.room.Insert; 6 | import android.arch.persistence.room.OnConflictStrategy; 7 | import android.arch.persistence.room.Query; 8 | import android.arch.persistence.room.Update; 9 | 10 | import com.fusionjack.adhell3.db.entity.AppInfo; 11 | 12 | import java.util.List; 13 | 14 | @Dao 15 | public interface AppInfoDao { 16 | @Insert(onConflict = OnConflictStrategy.REPLACE) 17 | void insertAll(List apps); 18 | 19 | @Insert(onConflict = OnConflictStrategy.REPLACE) 20 | void insert(AppInfo info); 21 | 22 | @Query("DELETE FROM AppInfo") 23 | void deleteAll(); 24 | 25 | 26 | @Query("SELECT * FROM AppInfo WHERE packageName = :packageName") 27 | AppInfo getByPackageName(String packageName); 28 | 29 | @Query("DELETE FROM AppInfo WHERE packageName = :packageName") 30 | void deleteAppInfoByPackageName(String packageName); 31 | 32 | @Query("SELECT MAX(id) FROM AppInfo") 33 | long getMaxId(); 34 | 35 | @Query("SELECT * FROM AppInfo WHERE adhellWhitelisted = 1") 36 | List getWhitelistedApps(); 37 | 38 | @Query("SELECT * FROM AppInfo WHERE disabled = 0 ORDER BY adhellWhitelisted DESC, appName ASC") 39 | LiveData> getAllSortedByWhitelist(); 40 | 41 | @Query("SELECT * FROM AppInfo WHERE system = 0 AND disabled = 0 ORDER BY appName ASC") 42 | List getUserApps(); 43 | 44 | @Query("SELECT * FROM AppInfo ORDER BY appName ASC") 45 | List getAll(); 46 | 47 | @Query("SELECT * FROM AppInfo ORDER BY installTime DESC") 48 | List getAllRecentSort(); 49 | 50 | @Query("SELECT * FROM AppInfo ORDER BY disabled DESC, appName ASC") 51 | List getAllSortedByDisabled(); 52 | 53 | @Query("SELECT * FROM AppInfo WHERE (appName LIKE :str OR packageName LIKE :str) ORDER BY appName ASC") 54 | List getAllAppsWithStrInName(String str); 55 | 56 | @Query("SELECT * FROM AppInfo WHERE (appName LIKE :str OR packageName LIKE :str) ORDER BY installTime DESC") 57 | List getAllAppsWithStrInNameTimeOrder(String str); 58 | 59 | @Query("SELECT * FROM AppInfo WHERE (appName LIKE :str OR packageName LIKE :str) ORDER BY disabled DESC, appName ASC") 60 | List getAllAppsWithStrInNameDisabledOrder(String str); 61 | 62 | @Query("SELECT * FROM AppInfo WHERE disabled = 1") 63 | List getDisabledApps(); 64 | 65 | @Query("SELECT * FROM AppInfo WHERE disabled = 0 ORDER BY appName ASC") 66 | List getEnabledApps(); 67 | 68 | @Query("SELECT * FROM AppInfo WHERE (appName LIKE :str OR packageName LIKE :str) AND disabled = 0 ORDER BY appName ASC") 69 | List getEnabledAppsAlphabetically(String str); 70 | 71 | @Query("SELECT * FROM AppInfo WHERE disabled = 0 ORDER BY installTime DESC") 72 | List getEnabledAppsInTimeOrder(); 73 | 74 | @Query("SELECT * FROM AppInfo WHERE (appName LIKE :str OR packageName LIKE :str) AND disabled = 0 ORDER BY installTime DESC") 75 | List getEnabledAppsInTimeOrder(String str); 76 | 77 | @Query("SELECT * FROM AppInfo ORDER BY mobileRestricted DESC, appName ASC") 78 | List getEnableAppsByMobileRestricted(); 79 | 80 | @Query("SELECT * FROM AppInfo WHERE (appName LIKE :str OR packageName LIKE :str) ORDER BY mobileRestricted DESC, appName ASC") 81 | List getEnableAppsByMobileRestricted(String str); 82 | 83 | @Query("SELECT * FROM AppInfo WHERE mobileRestricted = 1 AND disabled = 0") 84 | List getMobileRestrictedApps(); 85 | 86 | @Update 87 | void update(AppInfo appInfo); 88 | 89 | /*@Query("DELETE FROM AppInfo WHERE id = :id") 90 | void deleteAppInfoById(int id); 91 | 92 | @Query("SELECT * FROM AppInfo WHERE packageName LIKE :str ORDER BY appName ASC") 93 | List getAllPackagesWithStrInName(String str); 94 | 95 | @Query("SELECT * FROM AppInfo WHERE packageName LIKE :str ORDER BY installTime DESC") 96 | List getAllPackagesWithStrInNameAlphOrder(String str);*/ 97 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/dao/AppPermissionDao.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.dao; 2 | 3 | import android.arch.persistence.room.Dao; 4 | import android.arch.persistence.room.Insert; 5 | import android.arch.persistence.room.OnConflictStrategy; 6 | import android.arch.persistence.room.Query; 7 | 8 | import com.fusionjack.adhell3.db.entity.AppPermission; 9 | 10 | import java.util.List; 11 | 12 | @Dao 13 | public interface AppPermissionDao { 14 | 15 | @Query("SELECT * FROM AppPermission") 16 | List getAll(); 17 | 18 | @Insert(onConflict = OnConflictStrategy.REPLACE) 19 | void insert(AppPermission appPermission); 20 | 21 | @Insert(onConflict = OnConflictStrategy.REPLACE) 22 | void insertAll(List appPermissions); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/dao/BlockUrlDao.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.dao; 2 | 3 | import android.arch.persistence.room.Dao; 4 | import android.arch.persistence.room.Insert; 5 | import android.arch.persistence.room.OnConflictStrategy; 6 | import android.arch.persistence.room.Query; 7 | 8 | import com.fusionjack.adhell3.db.entity.BlockUrl; 9 | 10 | import java.util.List; 11 | 12 | @Dao 13 | public interface BlockUrlDao { 14 | 15 | @Query("SELECT * FROM BlockUrl") 16 | List getAll(); 17 | 18 | @Query("SELECT * FROM BlockUrl WHERE urlProviderId = :urlProviderId") 19 | List getUrlsByProviderId(long urlProviderId); 20 | 21 | @Query("DELETE FROM BlockUrl") 22 | void deleteAll(); 23 | 24 | @Insert(onConflict = OnConflictStrategy.REPLACE) 25 | void insertAll(List blockUrls); 26 | 27 | @Insert(onConflict = OnConflictStrategy.REPLACE) 28 | void insert(BlockUrl... blockUrls); 29 | 30 | @Query("SELECT * FROM BlockUrl WHERE urlProviderId = :urlProviderId AND url LIKE :url") 31 | List getByUrl(long urlProviderId, String url); 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/dao/BlockUrlProviderDao.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.dao; 2 | 3 | import android.arch.lifecycle.LiveData; 4 | import android.arch.persistence.room.Dao; 5 | import android.arch.persistence.room.Delete; 6 | import android.arch.persistence.room.Insert; 7 | import android.arch.persistence.room.OnConflictStrategy; 8 | import android.arch.persistence.room.Query; 9 | import android.arch.persistence.room.Update; 10 | 11 | import com.fusionjack.adhell3.db.entity.BlockUrlProvider; 12 | 13 | import java.util.List; 14 | 15 | @Dao 16 | public interface BlockUrlProviderDao { 17 | 18 | @Query("SELECT * FROM BlockUrlProviders") 19 | List getAll2(); 20 | 21 | @Query("SELECT * FROM BlockUrlProviders") 22 | LiveData> getAll(); 23 | 24 | @Query("SELECT * FROM BlockUrlProviders WHERE selected = :selected") 25 | List getBlockUrlProviderBySelectedFlag(int selected); 26 | 27 | @Query("SELECT * FROM BlockUrlProviders WHERE url = :url") 28 | BlockUrlProvider getByUrl(String url); 29 | 30 | @Insert(onConflict = OnConflictStrategy.REPLACE) 31 | long[] insertAll(BlockUrlProvider... urlProviders); 32 | 33 | @Update 34 | void updateBlockUrlProviders(BlockUrlProvider... blockUrlProviders); 35 | 36 | @Delete 37 | void delete(BlockUrlProvider blockUrlProvider); 38 | 39 | @Query("SELECT * FROM BlockUrlProviders WHERE deletable = 0") 40 | List getDefault(); 41 | 42 | @Query("DELETE FROM BlockUrlProviders WHERE deletable = 0") 43 | void deleteDefault(); 44 | 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/dao/DisabledPackageDao.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.dao; 2 | 3 | import android.arch.persistence.room.Dao; 4 | import android.arch.persistence.room.Insert; 5 | import android.arch.persistence.room.OnConflictStrategy; 6 | import android.arch.persistence.room.Query; 7 | import android.arch.persistence.room.TypeConverters; 8 | 9 | import com.fusionjack.adhell3.db.DateConverter; 10 | import com.fusionjack.adhell3.db.entity.DisabledPackage; 11 | import com.fusionjack.adhell3.db.entity.UserBlockUrl; 12 | 13 | import java.util.List; 14 | 15 | @Dao 16 | @TypeConverters(DateConverter.class) 17 | public interface DisabledPackageDao { 18 | 19 | @Query("SELECT * FROM DisabledPackage") 20 | List getAll(); 21 | 22 | @Insert 23 | void insertAll(List disabledPackages); 24 | 25 | @Insert(onConflict = OnConflictStrategy.REPLACE) 26 | void insert(DisabledPackage disabledPackage); 27 | 28 | @Query("DELETE FROM DisabledPackage WHERE packageName = :packageName") 29 | void deleteByPackageName(String packageName); 30 | 31 | @Query("DELETE FROM DisabledPackage") 32 | void deleteAll(); 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/dao/FirewallWhitelistedPackageDao.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.dao; 2 | 3 | import android.arch.persistence.room.Dao; 4 | import android.arch.persistence.room.Insert; 5 | import android.arch.persistence.room.OnConflictStrategy; 6 | import android.arch.persistence.room.Query; 7 | 8 | import com.fusionjack.adhell3.db.entity.FirewallWhitelistedPackage; 9 | 10 | import java.util.List; 11 | 12 | @Dao 13 | public interface FirewallWhitelistedPackageDao { 14 | 15 | @Query("SELECT * FROM FirewallWhitelistedPackage") 16 | List getAll(); 17 | 18 | @Insert(onConflict = OnConflictStrategy.REPLACE) 19 | void insertAll(List firewallWhitelistedPackages); 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/dao/PolicyPackageDao.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.dao; 2 | 3 | import android.arch.lifecycle.LiveData; 4 | import android.arch.persistence.room.Dao; 5 | import android.arch.persistence.room.Insert; 6 | import android.arch.persistence.room.OnConflictStrategy; 7 | import android.arch.persistence.room.Query; 8 | import android.arch.persistence.room.TypeConverters; 9 | 10 | import com.fusionjack.adhell3.db.DateConverter; 11 | import com.fusionjack.adhell3.db.entity.PolicyPackage; 12 | 13 | @Dao 14 | @TypeConverters(DateConverter.class) 15 | public interface PolicyPackageDao { 16 | 17 | @Query("SELECT * FROM PolicyPackage") 18 | LiveData getAllLiveData(); 19 | 20 | @Query("SELECT * FROM PolicyPackage WHERE id = :id") 21 | PolicyPackage getPolicyById(String id); 22 | 23 | @Insert(onConflict = OnConflictStrategy.REPLACE) 24 | void insert(PolicyPackage policyPackage); 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/dao/ReportBlockedUrlDao.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.dao; 2 | 3 | import android.arch.persistence.room.Dao; 4 | import android.arch.persistence.room.Insert; 5 | import android.arch.persistence.room.OnConflictStrategy; 6 | import android.arch.persistence.room.Query; 7 | import android.arch.persistence.room.TypeConverters; 8 | 9 | import com.fusionjack.adhell3.db.DateConverter; 10 | import com.fusionjack.adhell3.db.entity.ReportBlockedUrl; 11 | 12 | import java.util.List; 13 | 14 | @Dao 15 | @TypeConverters(DateConverter.class) 16 | public interface ReportBlockedUrlDao { 17 | 18 | @Insert(onConflict = OnConflictStrategy.REPLACE) 19 | void insert(ReportBlockedUrl reportBlockedUrl); 20 | 21 | @Insert 22 | void insertAll(List reportBlockedUrls); 23 | 24 | @Query("SELECT * FROM ReportBlockedUrl WHERE blockDate BETWEEN :startDate AND :endDate ORDER BY _id DESC") 25 | List getReportBlockUrlBetween(long startDate, long endDate); 26 | 27 | @Query("DELETE FROM ReportBlockedUrl WHERE blockDate < :blockDate") 28 | void deleteBefore(long blockDate); 29 | 30 | @Query("SELECT * FROM ReportBlockedUrl ORDER BY blockDate DESC LIMIT 1") 31 | ReportBlockedUrl getLastBlockedDomain(); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/dao/RestrictedPackageDao.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.dao; 2 | 3 | import android.arch.persistence.room.Dao; 4 | import android.arch.persistence.room.Insert; 5 | import android.arch.persistence.room.OnConflictStrategy; 6 | import android.arch.persistence.room.Query; 7 | import android.arch.persistence.room.TypeConverters; 8 | 9 | import com.fusionjack.adhell3.db.DateConverter; 10 | import com.fusionjack.adhell3.db.entity.RestrictedPackage; 11 | 12 | import java.util.List; 13 | 14 | @Dao 15 | @TypeConverters(DateConverter.class) 16 | public interface RestrictedPackageDao { 17 | 18 | @Query("SELECT * FROM RestrictedPackage") 19 | List getAll(); 20 | 21 | @Insert 22 | void insertAll(List restrictedPackages); 23 | 24 | @Insert(onConflict = OnConflictStrategy.REPLACE) 25 | void insert(RestrictedPackage restrictedPackage); 26 | 27 | @Query("DELETE FROM RestrictedPackage WHERE packageName = :packageName") 28 | void deleteByPackageName(String packageName); 29 | 30 | @Query("DELETE FROM RestrictedPackage") 31 | void deleteAll(); 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/dao/UserBlockUrlDao.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.dao; 2 | 3 | import android.arch.lifecycle.LiveData; 4 | import android.arch.persistence.room.Dao; 5 | import android.arch.persistence.room.Delete; 6 | import android.arch.persistence.room.Insert; 7 | import android.arch.persistence.room.OnConflictStrategy; 8 | import android.arch.persistence.room.Query; 9 | import android.arch.persistence.room.TypeConverters; 10 | 11 | import com.fusionjack.adhell3.db.DateConverter; 12 | import com.fusionjack.adhell3.db.entity.UserBlockUrl; 13 | 14 | import java.util.List; 15 | 16 | @Dao 17 | @TypeConverters(DateConverter.class) 18 | public interface UserBlockUrlDao { 19 | @Query("SELECT * FROM UserBlockUrl") 20 | LiveData> getAll(); 21 | 22 | @Query("SELECT * FROM UserBlockUrl") 23 | List getAll2(); 24 | 25 | @Insert(onConflict = OnConflictStrategy.REPLACE) 26 | long insert(UserBlockUrl userBlockUrl); 27 | 28 | @Delete 29 | void delete(UserBlockUrl userBlockUrl); 30 | 31 | @Query("DELETE FROM UserBlockUrl WHERE url = :url") 32 | void deleteByUrl(String url); 33 | 34 | @Query("SELECT * FROM UserBlockUrl WHERE url LIKE :url") 35 | List getByUrl(String url); 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/dao/WhiteUrlDao.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.dao; 2 | 3 | import android.arch.lifecycle.LiveData; 4 | import android.arch.persistence.room.Dao; 5 | import android.arch.persistence.room.Delete; 6 | import android.arch.persistence.room.Insert; 7 | import android.arch.persistence.room.OnConflictStrategy; 8 | import android.arch.persistence.room.Query; 9 | import android.arch.persistence.room.TypeConverters; 10 | 11 | import com.fusionjack.adhell3.db.DateConverter; 12 | import com.fusionjack.adhell3.db.entity.WhiteUrl; 13 | 14 | import java.util.List; 15 | 16 | @Dao 17 | @TypeConverters(DateConverter.class) 18 | public interface WhiteUrlDao { 19 | 20 | @Query("SELECT * FROM WhiteUrl") 21 | LiveData> getAll(); 22 | 23 | @Query("SELECT * FROM WhiteUrl") 24 | List getAll2(); 25 | 26 | @Insert(onConflict = OnConflictStrategy.REPLACE) 27 | void insert(WhiteUrl whiteUrl); 28 | 29 | @Query("DELETE FROM WhiteUrl WHERE url = :url") 30 | void deleteByUrl(String url); 31 | 32 | @Delete 33 | void delete(WhiteUrl whiteUrl); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/entity/AppInfo.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.entity; 2 | 3 | import android.arch.persistence.room.ColumnInfo; 4 | import android.arch.persistence.room.Entity; 5 | import android.arch.persistence.room.Index; 6 | import android.arch.persistence.room.PrimaryKey; 7 | import android.arch.persistence.room.TypeConverters; 8 | 9 | import com.fusionjack.adhell3.db.DateConverter; 10 | 11 | 12 | @Entity( 13 | tableName = "AppInfo", 14 | indices = {@Index("appName"), @Index("installTime"), @Index("disabled"), @Index("mobileRestricted")} 15 | ) 16 | @TypeConverters(DateConverter.class) 17 | public class AppInfo { 18 | @PrimaryKey 19 | public long id; 20 | 21 | @ColumnInfo(name = "packageName") 22 | public String packageName; 23 | 24 | @ColumnInfo(name = "appName") 25 | public String appName; 26 | 27 | @ColumnInfo(name = "installTime") 28 | public long installTime; 29 | 30 | @ColumnInfo(name = "system") 31 | public boolean system; 32 | 33 | @ColumnInfo(name = "adhellWhitelisted") 34 | public boolean adhellWhitelisted; 35 | 36 | @ColumnInfo(name = "disabled") 37 | public boolean disabled; 38 | 39 | @ColumnInfo(name = "mobileRestricted") 40 | public boolean mobileRestricted; 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/entity/AppPermission.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.entity; 2 | 3 | import android.arch.persistence.room.ColumnInfo; 4 | import android.arch.persistence.room.Entity; 5 | import android.arch.persistence.room.ForeignKey; 6 | import android.arch.persistence.room.Ignore; 7 | import android.arch.persistence.room.Index; 8 | import android.arch.persistence.room.PrimaryKey; 9 | 10 | 11 | @Entity( 12 | tableName = "AppPermission", 13 | indices = {@Index("policyPackageId")}, 14 | foreignKeys = @ForeignKey(entity = PolicyPackage.class, 15 | parentColumns = "id", 16 | childColumns = "policyPackageId") 17 | ) 18 | public class AppPermission { 19 | 20 | @Ignore 21 | public static final int STATUS_DISALLOW = -1; 22 | 23 | @Ignore 24 | public static final int STATUS_NONE = 0; 25 | 26 | @Ignore 27 | public static final int STATUS_ALLOW = 1; 28 | 29 | @PrimaryKey(autoGenerate = true) 30 | @ColumnInfo(name = "id") 31 | public long id; 32 | 33 | @ColumnInfo(name = "packageName") 34 | public String packageName; 35 | 36 | @ColumnInfo(name = "permissionName") 37 | public String permissionName; 38 | 39 | @ColumnInfo(name = "permissionStatus") 40 | public int permissionStatus; 41 | 42 | @ColumnInfo(name = "policyPackageId") 43 | public String policyPackageId; 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/entity/BlockUrl.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.entity; 2 | 3 | import android.arch.persistence.room.ColumnInfo; 4 | import android.arch.persistence.room.Entity; 5 | import android.arch.persistence.room.ForeignKey; 6 | import android.arch.persistence.room.Index; 7 | import android.arch.persistence.room.PrimaryKey; 8 | 9 | 10 | @Entity( 11 | tableName = "BlockUrl", 12 | indices = {@Index("urlProviderId")}, 13 | foreignKeys = @ForeignKey( 14 | entity = BlockUrlProvider.class, 15 | parentColumns = "_id", 16 | childColumns = "urlProviderId", 17 | onDelete = ForeignKey.CASCADE 18 | ) 19 | ) 20 | public class BlockUrl { 21 | @PrimaryKey(autoGenerate = true) 22 | @ColumnInfo(name = "_id") 23 | public long id; 24 | 25 | @ColumnInfo(name = "url") 26 | public String url; 27 | 28 | @ColumnInfo(name = "urlProviderId") 29 | public long urlProviderId; 30 | 31 | public BlockUrl(String url, long urlProviderId) { 32 | this.url = url; 33 | this.urlProviderId = urlProviderId; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/entity/BlockUrlProvider.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.entity; 2 | 3 | import android.arch.persistence.room.ColumnInfo; 4 | import android.arch.persistence.room.Entity; 5 | import android.arch.persistence.room.ForeignKey; 6 | import android.arch.persistence.room.Index; 7 | import android.arch.persistence.room.PrimaryKey; 8 | import android.arch.persistence.room.TypeConverters; 9 | 10 | import com.fusionjack.adhell3.db.DateConverter; 11 | 12 | import java.util.Date; 13 | 14 | @Entity(tableName = "BlockUrlProviders", 15 | indices = {@Index("policyPackageId")}, 16 | foreignKeys = @ForeignKey(entity = PolicyPackage.class, 17 | parentColumns = "id", 18 | childColumns = "policyPackageId")) 19 | @TypeConverters(DateConverter.class) 20 | public class BlockUrlProvider { 21 | @PrimaryKey(autoGenerate = true) 22 | @ColumnInfo(name = "_id") 23 | public long id; 24 | 25 | @ColumnInfo(name = "url") 26 | public String url; 27 | 28 | @ColumnInfo(name = "count") 29 | public int count; 30 | 31 | @ColumnInfo(name = "lastUpdated") 32 | public Date lastUpdated; 33 | 34 | @ColumnInfo(name = "deletable") 35 | public boolean deletable; 36 | 37 | @ColumnInfo(name = "selected") 38 | public boolean selected; 39 | 40 | @ColumnInfo(name = "policyPackageId") 41 | public String policyPackageId; 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/entity/DisabledPackage.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.entity; 2 | 3 | import android.arch.persistence.room.ColumnInfo; 4 | import android.arch.persistence.room.Entity; 5 | import android.arch.persistence.room.ForeignKey; 6 | import android.arch.persistence.room.Index; 7 | import android.arch.persistence.room.PrimaryKey; 8 | 9 | @Entity( 10 | tableName = "DisabledPackage", 11 | indices = {@Index("policyPackageId")}, 12 | foreignKeys = @ForeignKey(entity = PolicyPackage.class, 13 | parentColumns = "id", 14 | childColumns = "policyPackageId") 15 | ) 16 | public class DisabledPackage { 17 | 18 | @PrimaryKey(autoGenerate = true) 19 | @ColumnInfo(name = "id") 20 | public long id; 21 | 22 | @ColumnInfo(name = "packageName") 23 | public String packageName; 24 | 25 | @ColumnInfo(name = "policyPackageId") 26 | public String policyPackageId; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/entity/FirewallWhitelistedPackage.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.entity; 2 | 3 | import android.arch.persistence.room.ColumnInfo; 4 | import android.arch.persistence.room.Entity; 5 | import android.arch.persistence.room.ForeignKey; 6 | import android.arch.persistence.room.Ignore; 7 | import android.arch.persistence.room.Index; 8 | import android.arch.persistence.room.PrimaryKey; 9 | 10 | @Entity( 11 | tableName = "FirewallWhitelistedPackage", 12 | indices = {@Index("policyPackageId")}, 13 | foreignKeys = @ForeignKey(entity = PolicyPackage.class, 14 | parentColumns = "id", 15 | childColumns = "policyPackageId") 16 | ) 17 | public class FirewallWhitelistedPackage { 18 | 19 | @PrimaryKey(autoGenerate = true) 20 | @ColumnInfo(name = "id") 21 | public long id; 22 | 23 | @ColumnInfo(name = "packageName") 24 | public String packageName; 25 | 26 | @ColumnInfo(name = "policyPackageId") 27 | public String policyPackageId; 28 | 29 | public FirewallWhitelistedPackage() { 30 | } 31 | 32 | @Ignore 33 | public FirewallWhitelistedPackage(String packageName, String policyPackageId) { 34 | this.packageName = packageName; 35 | this.policyPackageId = policyPackageId; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/entity/PolicyPackage.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.entity; 2 | 3 | import android.arch.persistence.room.ColumnInfo; 4 | import android.arch.persistence.room.Entity; 5 | import android.arch.persistence.room.Ignore; 6 | import android.arch.persistence.room.PrimaryKey; 7 | import android.arch.persistence.room.TypeConverters; 8 | 9 | import com.fusionjack.adhell3.db.DateConverter; 10 | 11 | import java.util.Date; 12 | import java.util.List; 13 | 14 | import android.support.annotation.NonNull; 15 | 16 | @Entity( 17 | tableName = "PolicyPackage" 18 | ) 19 | @TypeConverters(DateConverter.class) 20 | public class PolicyPackage { 21 | 22 | @NonNull 23 | @PrimaryKey 24 | @ColumnInfo(name = "id") 25 | public String id = ""; 26 | 27 | @ColumnInfo(name = "name") 28 | public String name; 29 | 30 | @ColumnInfo(name = "description") 31 | public String description; 32 | 33 | @ColumnInfo(name = "active") 34 | public boolean active; 35 | 36 | @ColumnInfo(name = "createdAt") 37 | public Date createdAt; 38 | 39 | @ColumnInfo(name = "updatedAt") 40 | public Date updatedAt; 41 | 42 | @ColumnInfo(name = "numberOfDisabledPackages") 43 | public int numberOfDisabledPackages; 44 | 45 | @ColumnInfo(name = "numberOfHosts") 46 | public int numberOfHosts; 47 | 48 | @ColumnInfo(name = "numberOfUserBlockedDomains") 49 | public int numberOfUserBlockedDomains; 50 | 51 | @ColumnInfo(name = "numberOfUserWhitelistedDomains") 52 | public int numberOfUserWhitelistedDomains; 53 | 54 | @ColumnInfo(name = "numberOfChangedPermissions") 55 | public int numberOfChangedPermissions; 56 | 57 | @Ignore 58 | public List disabledPackages; 59 | 60 | @Ignore 61 | public List blockUrlProviders; 62 | 63 | @Ignore 64 | public List userBlockedDomains; 65 | 66 | @Ignore 67 | public List userWhitelistedDomains; 68 | 69 | @Ignore 70 | public List appPermissions; 71 | 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/entity/ReportBlockedUrl.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.entity; 2 | 3 | import android.arch.persistence.room.ColumnInfo; 4 | import android.arch.persistence.room.Entity; 5 | import android.arch.persistence.room.Ignore; 6 | import android.arch.persistence.room.PrimaryKey; 7 | import android.arch.persistence.room.TypeConverters; 8 | 9 | import com.fusionjack.adhell3.db.DateConverter; 10 | 11 | @Entity(tableName = "ReportBlockedUrl") 12 | @TypeConverters(DateConverter.class) 13 | public class ReportBlockedUrl { 14 | 15 | @PrimaryKey(autoGenerate = true) 16 | @ColumnInfo(name = "_id") 17 | public long id; 18 | public String url; 19 | public String packageName; 20 | public long blockDate; 21 | 22 | public ReportBlockedUrl() { 23 | } 24 | 25 | @Ignore 26 | public ReportBlockedUrl(String url, String packageName, long timestamp) { 27 | this.url = url; 28 | this.packageName = packageName; 29 | this.blockDate = timestamp; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return "ReportBlockedUrl{" + 35 | "id=" + id + 36 | ", url='" + url + '\'' + 37 | ", packageName='" + packageName + '\'' + 38 | ", blockDate=" + blockDate + 39 | '}'; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/entity/RestrictedPackage.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.entity; 2 | 3 | import android.arch.persistence.room.ColumnInfo; 4 | import android.arch.persistence.room.Entity; 5 | import android.arch.persistence.room.ForeignKey; 6 | import android.arch.persistence.room.Index; 7 | import android.arch.persistence.room.PrimaryKey; 8 | 9 | @Entity( 10 | tableName = "RestrictedPackage", 11 | indices = {@Index("policyPackageId")}, 12 | foreignKeys = @ForeignKey(entity = PolicyPackage.class, 13 | parentColumns = "id", 14 | childColumns = "policyPackageId") 15 | ) 16 | public class RestrictedPackage { 17 | 18 | @PrimaryKey(autoGenerate = true) 19 | @ColumnInfo(name = "id") 20 | public long id; 21 | 22 | @ColumnInfo(name = "packageName") 23 | public String packageName; 24 | 25 | @ColumnInfo(name = "policyPackageId") 26 | public String policyPackageId; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/entity/UserBlockUrl.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.entity; 2 | 3 | import android.arch.persistence.room.ColumnInfo; 4 | import android.arch.persistence.room.Entity; 5 | import android.arch.persistence.room.ForeignKey; 6 | import android.arch.persistence.room.Ignore; 7 | import android.arch.persistence.room.Index; 8 | import android.arch.persistence.room.PrimaryKey; 9 | import android.arch.persistence.room.TypeConverters; 10 | 11 | import com.fusionjack.adhell3.db.DateConverter; 12 | 13 | import java.util.Date; 14 | 15 | @Entity( 16 | tableName = "UserBlockUrl" 17 | ) 18 | @TypeConverters(DateConverter.class) 19 | public class UserBlockUrl { 20 | @PrimaryKey(autoGenerate = true) 21 | @ColumnInfo(name = "_id") 22 | public long id; 23 | 24 | @ColumnInfo(name = "url") 25 | public String url; 26 | 27 | public Date insertedAt; 28 | 29 | public UserBlockUrl() { 30 | } 31 | 32 | @Ignore 33 | public UserBlockUrl(String url) { 34 | this.insertedAt = new Date(); 35 | this.url = url; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/entity/WhiteUrl.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.entity; 2 | 3 | import android.arch.persistence.room.ColumnInfo; 4 | import android.arch.persistence.room.Entity; 5 | import android.arch.persistence.room.ForeignKey; 6 | import android.arch.persistence.room.Ignore; 7 | import android.arch.persistence.room.Index; 8 | import android.arch.persistence.room.PrimaryKey; 9 | import android.arch.persistence.room.TypeConverters; 10 | 11 | import com.fusionjack.adhell3.db.DateConverter; 12 | 13 | import java.util.Date; 14 | 15 | @Entity( 16 | tableName = "WhiteUrl" 17 | ) 18 | @TypeConverters(DateConverter.class) 19 | public class WhiteUrl { 20 | @PrimaryKey(autoGenerate = true) 21 | @ColumnInfo(name = "_id") 22 | public long id; 23 | 24 | @ColumnInfo(name = "url") 25 | public String url; 26 | 27 | public Date insertedAt; 28 | 29 | @Ignore 30 | public WhiteUrl(String url) { 31 | this.url = url; 32 | this.insertedAt = new Date(); 33 | } 34 | 35 | public WhiteUrl() { 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/migration/Migration_14_15.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.migration; 2 | 3 | import android.arch.persistence.db.SupportSQLiteDatabase; 4 | import android.arch.persistence.room.migration.Migration; 5 | 6 | 7 | public class Migration_14_15 extends Migration { 8 | 9 | public Migration_14_15(int startVersion, int endVersion) { 10 | super(startVersion, endVersion); 11 | } 12 | 13 | @Override 14 | public void migrate(SupportSQLiteDatabase supportSQLiteDatabase) { 15 | supportSQLiteDatabase.execSQL("ALTER TABLE AppInfo ADD COLUMN adhellWhitelisted INTEGER DEFAULT 0"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/migration/Migration_15_16.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.migration; 2 | 3 | import android.arch.persistence.db.SupportSQLiteDatabase; 4 | import android.arch.persistence.room.migration.Migration; 5 | 6 | public class Migration_15_16 extends Migration { 7 | 8 | public Migration_15_16(int startVersion, int endVersion) { 9 | super(startVersion, endVersion); 10 | } 11 | 12 | @Override 13 | public void migrate(SupportSQLiteDatabase supportSQLiteDatabase) { 14 | supportSQLiteDatabase.execSQL("ALTER TABLE AppInfo ADD COLUMN disabled INTEGER DEFAULT 0"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/migration/Migration_16_17.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.migration; 2 | 3 | import android.arch.persistence.db.SupportSQLiteDatabase; 4 | import android.arch.persistence.room.migration.Migration; 5 | import android.content.ContentValues; 6 | import android.database.sqlite.SQLiteDatabase; 7 | 8 | import java.util.Date; 9 | 10 | public class Migration_16_17 extends Migration { 11 | 12 | public Migration_16_17(int startVersion, int endVersion) { 13 | super(startVersion, endVersion); 14 | } 15 | 16 | @Override 17 | public void migrate(SupportSQLiteDatabase database) { 18 | 19 | database.execSQL("CREATE TABLE PolicyPackage " + 20 | "(id TEXT PRIMARY KEY, " + 21 | "name TEXT NOT NULL, " + 22 | "createdAt INTEGER, " + 23 | "updatedAt INTEGER) "); 24 | 25 | Date currentDate = new Date(); 26 | ContentValues contentValues = new ContentValues(); 27 | contentValues.put("id", "default-policy"); 28 | contentValues.put("name", "Default Policy"); 29 | contentValues.put("createdAt", currentDate.getTime()); 30 | contentValues.put("updatedAt", currentDate.getTime()); 31 | database.insert("PolicyPackage", SQLiteDatabase.CONFLICT_REPLACE, contentValues); 32 | 33 | database.execSQL("CREATE TABLE AppPermission " + 34 | "(id INTEGER PRIMARY KEY, " + 35 | "packageName TEXT NOT NULL, " + 36 | "permissionName TEXT NOT NULL, " + 37 | "permissionStatus INTEGER DEFAULT 0, " + 38 | "policyPackageId TEXT DEFAULT 'default-policy', " + 39 | "FOREIGN KEY (policyPackageId) REFERENCES PolicyPackage(id))"); 40 | database.execSQL("CREATE UNIQUE INDEX app_permission_policy_package_idx " + 41 | "ON AppPermission (packageName, permissionName, policyPackageId)"); 42 | 43 | database.execSQL("CREATE TABLE DisabledPackage " + 44 | "(id INTEGER PRIMARY KEY, " + 45 | "packageName TEXT NOT NULL, " + 46 | "policyPackageId TEXT DEFAULT 'default-policy', " + 47 | "FOREIGN KEY (policyPackageId) REFERENCES PolicyPackage(id))"); 48 | database.execSQL("CREATE UNIQUE INDEX disabled_package_policy_package_idx " + 49 | "ON DisabledPackage (packageName, policyPackageId)"); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/migration/Migration_17_18.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.migration; 2 | 3 | import android.arch.persistence.db.SupportSQLiteDatabase; 4 | import android.arch.persistence.room.migration.Migration; 5 | 6 | public class Migration_17_18 extends Migration { 7 | 8 | public Migration_17_18(int startVersion, int endVersion) { 9 | super(startVersion, endVersion); 10 | } 11 | 12 | @Override 13 | public void migrate(SupportSQLiteDatabase database) { 14 | database.execSQL("ALTER TABLE PolicyPackage ADD COLUMN active INTEGER DEFAULT 1"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/migration/Migration_18_19.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.migration; 2 | 3 | import android.arch.persistence.db.SupportSQLiteDatabase; 4 | import android.arch.persistence.room.migration.Migration; 5 | 6 | public class Migration_18_19 extends Migration { 7 | 8 | public Migration_18_19(int startVersion, int endVersion) { 9 | super(startVersion, endVersion); 10 | } 11 | 12 | @Override 13 | public void migrate(SupportSQLiteDatabase database) { 14 | database.execSQL("ALTER TABLE PolicyPackage ADD COLUMN description TEXT"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/migration/Migration_19_20.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.migration; 2 | 3 | import android.arch.persistence.db.SupportSQLiteDatabase; 4 | import android.arch.persistence.room.migration.Migration; 5 | 6 | public class Migration_19_20 extends Migration { 7 | 8 | public Migration_19_20(int startVersion, int endVersion) { 9 | super(startVersion, endVersion); 10 | } 11 | 12 | @Override 13 | public void migrate(SupportSQLiteDatabase database) { 14 | database.execSQL("CREATE TABLE FirewallWhitelistedPackage " + 15 | "(id INTEGER PRIMARY KEY, " + 16 | "packageName TEXT NOT NULL, " + 17 | "policyPackageId TEXT DEFAULT 'default-policy', " + 18 | "FOREIGN KEY (policyPackageId) REFERENCES PolicyPackage(id))"); 19 | database.execSQL("CREATE UNIQUE INDEX firewall_whitelisted_package_policy_package_idx " + 20 | "ON FirewallWhitelistedPackage (packageName, policyPackageId)"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/migration/Migration_20_21.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.migration; 2 | 3 | import android.arch.persistence.db.SupportSQLiteDatabase; 4 | import android.arch.persistence.room.migration.Migration; 5 | 6 | public class Migration_20_21 extends Migration { 7 | 8 | public Migration_20_21(int startVersion, int endVersion) { 9 | super(startVersion, endVersion); 10 | } 11 | 12 | @Override 13 | public void migrate(SupportSQLiteDatabase database) { 14 | database.execSQL("ALTER TABLE BlockUrlProviders ADD COLUMN policyPackageId TEXT DEFAULT 'default-policy' REFERENCES PolicyPackage(id)"); 15 | database.execSQL("ALTER TABLE UserBlockUrl ADD COLUMN policyPackageId TEXT DEFAULT 'default-policy' REFERENCES PolicyPackage(id)"); 16 | database.execSQL("ALTER TABLE WhiteUrl ADD COLUMN policyPackageId TEXT DEFAULT 'default-policy' REFERENCES PolicyPackage(id)"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/migration/Migration_21_22.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.migration; 2 | 3 | import android.arch.persistence.db.SupportSQLiteDatabase; 4 | import android.arch.persistence.room.migration.Migration; 5 | 6 | public class Migration_21_22 extends Migration { 7 | 8 | public Migration_21_22(int startVersion, int endVersion) { 9 | super(startVersion, endVersion); 10 | } 11 | 12 | @Override 13 | public void migrate(SupportSQLiteDatabase database) { 14 | database.execSQL("ALTER TABLE PolicyPackage ADD COLUMN numberOfDisabledPackages INTEGER DEFAULT 0"); 15 | database.execSQL("ALTER TABLE PolicyPackage ADD COLUMN numberOfHosts INTEGER DEFAULT 0"); 16 | database.execSQL("ALTER TABLE PolicyPackage ADD COLUMN numberOfUserBlockedDomains INTEGER DEFAULT 0"); 17 | database.execSQL("ALTER TABLE PolicyPackage ADD COLUMN numberOfUserWhitelistedDomains INTEGER DEFAULT 0"); 18 | database.execSQL("ALTER TABLE PolicyPackage ADD COLUMN numberOfChangedPermissions INTEGER DEFAULT 0"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/migration/Migration_22_23.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.migration; 2 | 3 | import android.arch.persistence.db.SupportSQLiteDatabase; 4 | import android.arch.persistence.room.migration.Migration; 5 | 6 | public class Migration_22_23 extends Migration { 7 | 8 | public Migration_22_23(int startVersion, int endVersion) { 9 | super(startVersion, endVersion); 10 | } 11 | 12 | @Override 13 | public void migrate(SupportSQLiteDatabase database) { 14 | database.execSQL("CREATE TABLE RestrictedPackage " + 15 | "(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " + 16 | "packageName TEXT, " + 17 | "policyPackageId TEXT, " + 18 | "FOREIGN KEY (policyPackageId) REFERENCES PolicyPackage(id))"); 19 | database.execSQL("CREATE INDEX index_RestrictedPackage_policyPackageId " + 20 | "ON RestrictedPackage (policyPackageId)"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/repository/AppInfoRepository.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.repository; 2 | 3 | public class AppInfoRepository 4 | {} -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/repository/BlockUrlProviderRepository.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.repository; 2 | 3 | public class BlockUrlProviderRepository { 4 | } 5 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/db/repository/BlockUrlRepository.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.db.repository; 2 | 3 | 4 | public class BlockUrlRepository { 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/dialogfragment/AdhellNotSupportedDialogFragment.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.dialogfragment; 2 | 3 | 4 | import android.support.v4.app.DialogFragment; 5 | import android.os.Bundle; 6 | import android.support.annotation.Nullable; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | 11 | import com.fusionjack.adhell3.R; 12 | 13 | public class AdhellNotSupportedDialogFragment extends DialogFragment { 14 | 15 | public AdhellNotSupportedDialogFragment() { 16 | } 17 | 18 | public static AdhellNotSupportedDialogFragment newInstance(String title) { 19 | AdhellNotSupportedDialogFragment adhellNotSupportedDialogFragment = new AdhellNotSupportedDialogFragment(); 20 | Bundle args = new Bundle(); 21 | args.putString("title", title); 22 | adhellNotSupportedDialogFragment.setArguments(args); 23 | return adhellNotSupportedDialogFragment; 24 | } 25 | 26 | 27 | @Nullable 28 | @Override 29 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { 30 | return inflater.inflate(R.layout.dialog_fragment_adhell_not_supported, container); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/dialogfragment/NoInternetConnectionDialogFragment.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.dialogfragment; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.app.DialogFragment; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | import com.fusionjack.adhell3.R; 11 | 12 | public class NoInternetConnectionDialogFragment extends DialogFragment { 13 | 14 | public NoInternetConnectionDialogFragment() { 15 | } 16 | 17 | public static NoInternetConnectionDialogFragment newInstance(String title) { 18 | NoInternetConnectionDialogFragment noInternetConnectionDialogFragment = new NoInternetConnectionDialogFragment(); 19 | Bundle args = new Bundle(); 20 | args.putString("title", title); 21 | noInternetConnectionDialogFragment.setArguments(args); 22 | return noInternetConnectionDialogFragment; 23 | } 24 | 25 | @Nullable 26 | @Override 27 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { 28 | return inflater.inflate(R.layout.dialog_fragment_no_internet_connection, container); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/fragments/AdhellNotSupportedFragment.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.fragments; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.Fragment; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | 9 | import com.fusionjack.adhell3.R; 10 | 11 | public class AdhellNotSupportedFragment extends Fragment { 12 | private static final String TAG = AdhellNotSupportedFragment.class.getCanonicalName(); 13 | 14 | @Override 15 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 16 | Bundle savedInstanceState) { 17 | View view = inflater.inflate(R.layout.fragment_adhell_not_supported, container, false); 18 | return view; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/fragments/AdhellPermissionInAppsFragment.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.fragments; 2 | 3 | import android.arch.lifecycle.ViewModelProviders; 4 | import android.content.pm.PackageManager; 5 | import android.os.Bundle; 6 | import android.support.annotation.Nullable; 7 | import android.support.v4.app.Fragment; 8 | import android.support.v7.app.AppCompatActivity; 9 | import android.support.v7.widget.DividerItemDecoration; 10 | import android.support.v7.widget.LinearLayoutManager; 11 | import android.support.v7.widget.RecyclerView; 12 | import android.view.LayoutInflater; 13 | import android.view.View; 14 | import android.view.ViewGroup; 15 | 16 | import com.fusionjack.adhell3.App; 17 | import com.fusionjack.adhell3.R; 18 | import com.fusionjack.adhell3.adapter.AdhellPermissionInAppsAdapter; 19 | import com.fusionjack.adhell3.db.AppDatabase; 20 | import com.fusionjack.adhell3.db.entity.AppInfo; 21 | import com.fusionjack.adhell3.model.AdhellPermissionInfo; 22 | import com.fusionjack.adhell3.viewmodel.SharedAppPermissionViewModel; 23 | 24 | import java.util.List; 25 | 26 | import javax.inject.Inject; 27 | 28 | public class AdhellPermissionInAppsFragment extends Fragment { 29 | private RecyclerView permissionInAppsRecyclerView; 30 | private AppCompatActivity parentActivity; 31 | private AppDatabase appDatabase; 32 | 33 | @Inject 34 | PackageManager packageManager; 35 | 36 | @Override 37 | public void onCreate(@Nullable Bundle savedInstanceState) { 38 | super.onCreate(savedInstanceState); 39 | App.get().getAppComponent().inject(this); 40 | appDatabase = AppDatabase.getAppDatabase(getContext()); 41 | parentActivity = (AppCompatActivity) getActivity(); 42 | } 43 | 44 | @Nullable 45 | @Override 46 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 47 | if (parentActivity.getSupportActionBar() != null) { 48 | parentActivity.getSupportActionBar().setDisplayHomeAsUpEnabled(true); 49 | parentActivity.getSupportActionBar().setHomeButtonEnabled(true); 50 | } 51 | SharedAppPermissionViewModel sharedAppPermissionViewModel = ViewModelProviders.of(getActivity()).get(SharedAppPermissionViewModel.class); 52 | View view = inflater.inflate(R.layout.fragment_permission_in_apps, container, false); 53 | permissionInAppsRecyclerView = view.findViewById(R.id.permissionInAppsRecyclerView); 54 | permissionInAppsRecyclerView.setLayoutManager(new LinearLayoutManager(this.getContext())); 55 | RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(this.getContext(), DividerItemDecoration.VERTICAL); 56 | permissionInAppsRecyclerView.addItemDecoration(itemDecoration); 57 | 58 | sharedAppPermissionViewModel.getSelected().observe(this, permissionInfo -> { 59 | if (permissionInfo != null) { 60 | getActivity().setTitle(permissionInfo.name); 61 | List appInfos = AdhellPermissionInfo.getAppsByPermission(permissionInfo.name, appDatabase, packageManager); 62 | AdhellPermissionInAppsAdapter adhellPermissionInAppsAdapter = new AdhellPermissionInAppsAdapter(appInfos); 63 | adhellPermissionInAppsAdapter.currentPermissionName = permissionInfo.name; 64 | adhellPermissionInAppsAdapter.updatePermissionBlacklistedPackages(); 65 | permissionInAppsRecyclerView.setAdapter(adhellPermissionInAppsAdapter); 66 | adhellPermissionInAppsAdapter.notifyDataSetChanged(); 67 | } 68 | }); 69 | return view; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/fragments/AppListFragment.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.fragments; 2 | 3 | import android.arch.lifecycle.ViewModelProviders; 4 | import android.os.Bundle; 5 | import android.support.v4.app.Fragment; 6 | import android.text.Editable; 7 | import android.text.TextWatcher; 8 | import android.util.Log; 9 | import android.view.LayoutInflater; 10 | import android.view.View; 11 | import android.view.ViewGroup; 12 | import android.widget.EditText; 13 | import android.widget.ListView; 14 | 15 | import com.fusionjack.adhell3.R; 16 | import com.fusionjack.adhell3.adapter.AppWhitelistAdapter; 17 | import com.fusionjack.adhell3.db.entity.AppInfo; 18 | import com.fusionjack.adhell3.viewmodel.AdhellWhitelistAppsViewModel; 19 | 20 | 21 | public class AppListFragment extends Fragment { 22 | private static final String TAG = AppListFragment.class.getCanonicalName(); 23 | private ListView appListView; 24 | private AppWhitelistAdapter appWhitelistAdapter; 25 | private EditText adblockEnabledAppSearchEditText; 26 | 27 | @Override 28 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 29 | Bundle savedInstanceState) { 30 | this.getActivity().setTitle(R.string.adblock_whitelist); 31 | View view = inflater.inflate(R.layout.fragment_app_list, container, false); 32 | appListView = view.findViewById(R.id.appList); 33 | adblockEnabledAppSearchEditText = view.findViewById(R.id.adblockEnabledAppSearchEditText); 34 | 35 | adblockEnabledAppSearchEditText.addTextChangedListener(new TextWatcher() { 36 | @Override 37 | public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { 38 | 39 | } 40 | 41 | @Override 42 | public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { 43 | // charSequence.toString() 44 | 45 | 46 | } 47 | 48 | @Override 49 | public void afterTextChanged(Editable editable) { 50 | if (appWhitelistAdapter != null) { 51 | appWhitelistAdapter.getFilter().filter(editable.toString()); 52 | } 53 | } 54 | }); 55 | 56 | AdhellWhitelistAppsViewModel adhellWhitelistAppsViewModel = ViewModelProviders.of(getActivity()).get(AdhellWhitelistAppsViewModel.class); 57 | adhellWhitelistAppsViewModel.getSortedAppInfo().observe(this, appInfos -> { 58 | if (appWhitelistAdapter == null) { 59 | appWhitelistAdapter = new AppWhitelistAdapter(this.getContext(), appInfos); 60 | appListView.setAdapter(appWhitelistAdapter); 61 | } else { 62 | appWhitelistAdapter.notifyDataSetChanged(); 63 | } 64 | }); 65 | 66 | appListView.setOnItemClickListener((parent, view1, position, id) -> { 67 | AppInfo appInfo = (AppInfo) parent.getItemAtPosition(position); 68 | Log.d(TAG, "Will toggle app: " + appInfo.packageName); 69 | adhellWhitelistAppsViewModel.toggleApp(appInfo); 70 | }); 71 | return view; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/fragments/BlockCustomUrlFragment.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.fragments; 2 | 3 | import android.content.Context; 4 | import android.os.AsyncTask; 5 | import android.os.Bundle; 6 | import android.support.annotation.Nullable; 7 | import android.support.v4.app.Fragment; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.widget.ArrayAdapter; 12 | import android.widget.Button; 13 | import android.widget.EditText; 14 | import android.widget.ListView; 15 | import android.widget.Toast; 16 | 17 | import com.fusionjack.adhell3.R; 18 | import com.fusionjack.adhell3.db.AppDatabase; 19 | import com.fusionjack.adhell3.db.entity.UserBlockUrl; 20 | import com.fusionjack.adhell3.utils.BlockUrlPatternsMatch; 21 | 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | import java.util.StringTokenizer; 25 | 26 | public class BlockCustomUrlFragment extends Fragment { 27 | 28 | private List customUrlsToBlock; 29 | private Context context; 30 | private AppDatabase appDatabase; 31 | private ArrayAdapter itemsAdapter; 32 | 33 | @Override 34 | public void onCreate(@Nullable Bundle savedInstanceState) { 35 | super.onCreate(savedInstanceState); 36 | appDatabase = AppDatabase.getAppDatabase(getContext()); 37 | customUrlsToBlock = new ArrayList<>(); 38 | context = this.getActivity(); 39 | } 40 | 41 | @Nullable 42 | @Override 43 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { 44 | View view = inflater.inflate(R.layout.fragment_manual_url_block, container, false); 45 | ListView listView = (ListView) view.findViewById(R.id.customUrlsListView); 46 | appDatabase.userBlockUrlDao() 47 | .getAll() 48 | .observe(this, userBlockUrls -> { 49 | customUrlsToBlock.clear(); 50 | if (userBlockUrls != null) { 51 | for (UserBlockUrl userBlockUrl : userBlockUrls) { 52 | customUrlsToBlock.add(userBlockUrl.url); 53 | } 54 | } 55 | itemsAdapter = new ArrayAdapter<>(this.getActivity(), android.R.layout.simple_list_item_1, customUrlsToBlock); 56 | listView.setAdapter(itemsAdapter); 57 | }); 58 | 59 | listView.setOnItemClickListener((parent, view1, position, id) -> { 60 | AsyncTask.execute(() -> appDatabase.userBlockUrlDao().deleteByUrl(customUrlsToBlock.get(position))); 61 | itemsAdapter.notifyDataSetChanged(); 62 | Toast.makeText(context, "Url removed", Toast.LENGTH_SHORT).show(); 63 | }); 64 | 65 | final EditText addBlockedUrlEditText = (EditText) view.findViewById(R.id.addBlockedUrlEditText); 66 | Button addCustomBlockedUrlButton = (Button) view.findViewById(R.id.addCustomBlockedUrlButton); 67 | addCustomBlockedUrlButton.setOnClickListener(v -> { 68 | String urlToAdd = addBlockedUrlEditText.getText().toString().trim().toLowerCase(); 69 | if (urlToAdd.indexOf('|') == -1) { 70 | if (!BlockUrlPatternsMatch.isUrlValid(urlToAdd)) { 71 | Toast.makeText(context, "Url not valid. Please check", Toast.LENGTH_SHORT).show(); 72 | return; 73 | } 74 | } else { 75 | // packageName|ipAddress|port 76 | StringTokenizer tokens = new StringTokenizer(urlToAdd, "|"); 77 | if (tokens.countTokens() != 3) { 78 | Toast.makeText(context, "Rule not valid. Please check", Toast.LENGTH_SHORT).show(); 79 | return; 80 | } 81 | } 82 | 83 | AsyncTask.execute(() -> { 84 | UserBlockUrl userBlockUrl = new UserBlockUrl(urlToAdd); 85 | appDatabase.userBlockUrlDao().insert(userBlockUrl); 86 | }); 87 | addBlockedUrlEditText.setText(""); 88 | if (urlToAdd.indexOf('|') == -1) { 89 | Toast.makeText(context, "Url has been added", Toast.LENGTH_SHORT).show(); 90 | } else { 91 | Toast.makeText(context, "Rule has been added", Toast.LENGTH_SHORT).show(); 92 | } 93 | }); 94 | return view; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/fragments/BlockedUrlSettingFragment.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.fragments; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.app.Fragment; 6 | import android.support.v4.app.FragmentManager; 7 | import android.support.v4.app.FragmentTransaction; 8 | import android.util.Log; 9 | import android.view.LayoutInflater; 10 | import android.view.View; 11 | import android.view.ViewGroup; 12 | import android.widget.Button; 13 | 14 | import com.fusionjack.adhell3.R; 15 | import com.fusionjack.adhell3.blocker.ContentBlocker; 16 | import com.fusionjack.adhell3.blocker.ContentBlocker56; 17 | import com.fusionjack.adhell3.blocker.ContentBlocker57; 18 | import com.fusionjack.adhell3.utils.DeviceAdminInteractor; 19 | 20 | public class BlockedUrlSettingFragment extends Fragment { 21 | private static final String TAG = BlockedUrlSettingFragment.class.getCanonicalName(); 22 | private ContentBlocker contentBlocker; 23 | private FragmentManager fragmentManager; 24 | 25 | @Override 26 | public void onCreate(@Nullable Bundle savedInstanceState) { 27 | super.onCreate(savedInstanceState); 28 | contentBlocker = DeviceAdminInteractor.getInstance().getContentBlocker(); 29 | fragmentManager = getActivity().getSupportFragmentManager(); 30 | } 31 | 32 | @Nullable 33 | @Override 34 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { 35 | View view = inflater.inflate(R.layout.fragment_blocked_url_settings, container, false); 36 | Button seeStandardPackageButton = (Button) view.findViewById(R.id.seeStandardPackageButton); 37 | seeStandardPackageButton.setOnClickListener(v -> { 38 | Log.d(TAG, "Edit button click in Fragment1"); 39 | FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 40 | fragmentTransaction.replace(R.id.fragmentContainer, new WhitelistFragment()); 41 | fragmentTransaction.addToBackStack("manage_url_to_manage_standard"); 42 | fragmentTransaction.commit(); 43 | }); 44 | 45 | Button addCustomBlockedUrl = (Button) view.findViewById(R.id.addCustomBlockedUrl); 46 | addCustomBlockedUrl.setOnClickListener(v -> { 47 | FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 48 | fragmentTransaction.replace(R.id.fragmentContainer, new BlockCustomUrlFragment()); 49 | fragmentTransaction.addToBackStack("manage_url_to_add_custom"); 50 | fragmentTransaction.commit(); 51 | }); 52 | 53 | Button showCustomUrlProvidersFragmentButton = (Button) view.findViewById(R.id.showCustomUrlProvidersFragmentButton); 54 | if (contentBlocker instanceof ContentBlocker56 || contentBlocker instanceof ContentBlocker57) { 55 | showCustomUrlProvidersFragmentButton.setOnClickListener(v -> { 56 | FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 57 | fragmentTransaction.replace(R.id.fragmentContainer, new CustomBlockUrlProviderFragment()); 58 | fragmentTransaction.addToBackStack("manage_custom_url_providers"); 59 | fragmentTransaction.commit(); 60 | }); 61 | } else { 62 | showCustomUrlProvidersFragmentButton.setVisibility(View.GONE); 63 | } 64 | 65 | Button showBlockedUrls = (Button) view.findViewById(R.id.showBlockedUrls); 66 | showBlockedUrls.setOnClickListener(v -> { 67 | FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 68 | fragmentTransaction.replace(R.id.fragmentContainer, new ShowBlockUrlFragment()); 69 | fragmentTransaction.addToBackStack("manage_url_to_add_custom"); 70 | fragmentTransaction.commit(); 71 | }); 72 | 73 | return view; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/fragments/LoadAppAsyncTask.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.fragments; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.pm.PackageManager; 6 | import android.os.AsyncTask; 7 | import android.widget.ListView; 8 | 9 | import com.fusionjack.adhell3.adapter.AppInfoAdapter; 10 | import com.fusionjack.adhell3.db.AppDatabase; 11 | import com.fusionjack.adhell3.db.entity.AppInfo; 12 | 13 | import java.lang.ref.WeakReference; 14 | import java.util.List; 15 | 16 | public class LoadAppAsyncTask extends AsyncTask> { 17 | 18 | static final int SORTED_DISABLED_ALPHABETICALLY = 0; 19 | static final int SORTED_DISABLED_INSTALL_TIME = 1; 20 | static final int SORTED_DISABLED = 2; 21 | static final int SORTED_RESTRICTED_ALPHABETICALLY = 3; 22 | static final int SORTED_RESTRICTED_INSTALL_TIME = 4; 23 | static final int SORTED_RESTRICTED = 5; 24 | 25 | private WeakReference contextReference; 26 | private AppDatabase appDatabase; 27 | private PackageManager packageManager; 28 | private String text; 29 | private int sortState; 30 | private int layout; 31 | private boolean disabler; 32 | 33 | LoadAppAsyncTask(String text, int sortState, int layout, boolean disabler, 34 | Context context, AppDatabase appDatabase, PackageManager packageManager) { 35 | this.text = text; 36 | this.sortState = sortState; 37 | this.layout = layout; 38 | this.disabler = disabler; 39 | this.contextReference = new WeakReference<>(context); 40 | this.appDatabase = appDatabase; 41 | this.packageManager = packageManager; 42 | } 43 | 44 | @Override 45 | protected List doInBackground(Void... voids) { 46 | return getListFromDb(); 47 | } 48 | 49 | @Override 50 | protected void onPostExecute(List packageList) { 51 | Context context = contextReference.get(); 52 | if (context != null) { 53 | AppInfoAdapter adapter = new AppInfoAdapter(packageList, disabler, context, packageManager); 54 | ListView listView = ((Activity)context).findViewById(layout); 55 | listView.setAdapter(adapter); 56 | listView.invalidateViews(); 57 | } 58 | } 59 | 60 | private List getListFromDb() { 61 | String filterText = '%' + text + '%'; 62 | switch (sortState) { 63 | case SORTED_DISABLED_ALPHABETICALLY: 64 | if (text.length() == 0) { 65 | return appDatabase.applicationInfoDao().getAll(); 66 | } 67 | return appDatabase.applicationInfoDao().getAllAppsWithStrInName(filterText); 68 | case SORTED_DISABLED_INSTALL_TIME: 69 | if (text.length() == 0) { 70 | return appDatabase.applicationInfoDao().getAllRecentSort(); 71 | } 72 | return appDatabase.applicationInfoDao().getAllAppsWithStrInNameTimeOrder(filterText); 73 | case SORTED_DISABLED: 74 | if (text.length() == 0) { 75 | return appDatabase.applicationInfoDao().getAllSortedByDisabled(); 76 | } 77 | return appDatabase.applicationInfoDao().getAllAppsWithStrInNameDisabledOrder(filterText); 78 | case SORTED_RESTRICTED_ALPHABETICALLY: 79 | if (text.length() == 0) { 80 | return appDatabase.applicationInfoDao().getEnabledApps(); 81 | } 82 | return appDatabase.applicationInfoDao().getEnabledAppsAlphabetically(filterText); 83 | case SORTED_RESTRICTED_INSTALL_TIME: 84 | if (text.length() == 0) { 85 | return appDatabase.applicationInfoDao().getEnabledAppsInTimeOrder(); 86 | } 87 | return appDatabase.applicationInfoDao().getEnabledAppsInTimeOrder(filterText); 88 | case SORTED_RESTRICTED: 89 | if (text.length() == 0) { 90 | return appDatabase.applicationInfoDao().getEnableAppsByMobileRestricted(); 91 | } 92 | return appDatabase.applicationInfoDao().getEnableAppsByMobileRestricted(filterText); 93 | } 94 | return null; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/fragments/RefreshAppAsyncTask.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.fragments; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.pm.PackageManager; 6 | import android.os.AsyncTask; 7 | import android.support.v4.widget.SwipeRefreshLayout; 8 | 9 | import com.fusionjack.adhell3.R; 10 | import com.fusionjack.adhell3.db.AppDatabase; 11 | import com.fusionjack.adhell3.db.entity.AppInfo; 12 | import com.fusionjack.adhell3.db.entity.DisabledPackage; 13 | import com.fusionjack.adhell3.db.entity.RestrictedPackage; 14 | import com.fusionjack.adhell3.utils.AdhellAppIntegrity; 15 | import com.fusionjack.adhell3.utils.AppsListDBInitializer; 16 | 17 | import java.lang.ref.WeakReference; 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | 21 | public class RefreshAppAsyncTask extends AsyncTask { 22 | private WeakReference contextReference; 23 | private AppDatabase appDatabase; 24 | private PackageManager packageManager; 25 | private int sortState; 26 | private int layout; 27 | private boolean disabler; 28 | 29 | RefreshAppAsyncTask(int sortState, int layout, boolean disabler, 30 | Context context, AppDatabase appDatabase, PackageManager packageManager) { 31 | this.sortState = sortState; 32 | this.layout = layout; 33 | this.disabler = disabler; 34 | this.contextReference = new WeakReference<>(context); 35 | this.appDatabase = appDatabase; 36 | this.packageManager = packageManager; 37 | } 38 | 39 | @Override 40 | protected Void doInBackground(Void... voids) { 41 | // Get first disabled and restricted apps before they get deleted 42 | List disabledApps = appDatabase.applicationInfoDao().getDisabledApps(); 43 | List restrictedApps = appDatabase.applicationInfoDao().getMobileRestrictedApps(); 44 | 45 | // Delete all apps info 46 | appDatabase.applicationInfoDao().deleteAll(); 47 | AppsListDBInitializer.getInstance().fillPackageDb(packageManager); 48 | 49 | // Disabled apps 50 | appDatabase.disabledPackageDao().deleteAll(); 51 | List disabledPackages = new ArrayList<>(); 52 | for (AppInfo oldAppInfo : disabledApps) { 53 | AppInfo newAppInfo = appDatabase.applicationInfoDao().getByPackageName(oldAppInfo.packageName); 54 | if (newAppInfo != null) { 55 | newAppInfo.disabled = true; 56 | appDatabase.applicationInfoDao().insert(newAppInfo); 57 | 58 | DisabledPackage disabledPackage = new DisabledPackage(); 59 | disabledPackage.packageName = newAppInfo.packageName; 60 | disabledPackage.policyPackageId = AdhellAppIntegrity.DEFAULT_POLICY_ID; 61 | disabledPackages.add(disabledPackage); 62 | } 63 | } 64 | appDatabase.disabledPackageDao().insertAll(disabledPackages); 65 | 66 | // Restricted apps 67 | appDatabase.restrictedPackageDao().deleteAll(); 68 | List restrictedPackages = new ArrayList<>(); 69 | for (AppInfo oldAppInfo : restrictedApps) { 70 | AppInfo newAppInfo = appDatabase.applicationInfoDao().getByPackageName(oldAppInfo.packageName); 71 | if (newAppInfo != null) { 72 | newAppInfo.mobileRestricted = true; 73 | appDatabase.applicationInfoDao().insert(newAppInfo); 74 | 75 | RestrictedPackage restrictedPackage = new RestrictedPackage(); 76 | restrictedPackage.packageName = newAppInfo.packageName; 77 | restrictedPackage.policyPackageId = AdhellAppIntegrity.DEFAULT_POLICY_ID; 78 | restrictedPackages.add(restrictedPackage); 79 | } 80 | } 81 | appDatabase.restrictedPackageDao().insertAll(restrictedPackages); 82 | 83 | return null; 84 | } 85 | 86 | @Override 87 | protected void onPostExecute(Void aVoid) { 88 | Context context = contextReference.get(); 89 | if (context != null) { 90 | SwipeRefreshLayout swipeContainer = ((Activity) context).findViewById(R.id.swipeContainer); 91 | swipeContainer.setRefreshing(false); 92 | 93 | new LoadAppAsyncTask("", sortState, layout, disabler, context, appDatabase, packageManager).execute(); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/fragments/WhitelistFragment.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.fragments; 2 | 3 | import android.os.AsyncTask; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.support.v4.app.Fragment; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.ArrayAdapter; 11 | import android.widget.Button; 12 | import android.widget.EditText; 13 | import android.widget.ListView; 14 | import android.widget.Toast; 15 | 16 | import com.fusionjack.adhell3.R; 17 | import com.fusionjack.adhell3.db.AppDatabase; 18 | import com.fusionjack.adhell3.db.entity.WhiteUrl; 19 | import com.fusionjack.adhell3.utils.BlockUrlPatternsMatch; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | import java.util.StringTokenizer; 24 | 25 | 26 | public class WhitelistFragment extends Fragment { 27 | private static final String TAG = WhitelistFragment.class.getCanonicalName(); 28 | private ListView whiteUrlListView; 29 | private Button addWhitelistUrl; 30 | private EditText whitelistUrlEditText; 31 | private ArrayAdapter itemsAdapter; 32 | private List whitelist; 33 | private AppDatabase appDatabase; 34 | 35 | @Override 36 | public void onCreate(@Nullable Bundle savedInstanceState) { 37 | super.onCreate(savedInstanceState); 38 | appDatabase = AppDatabase.getAppDatabase(getContext()); 39 | whitelist = new ArrayList<>(); 40 | } 41 | 42 | @Override 43 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 44 | Bundle savedInstanceState) { 45 | final View view = inflater.inflate(R.layout.fragment_white_list, container, false); 46 | addWhitelistUrl = view.findViewById(R.id.addWhitelistUrl); 47 | whiteUrlListView = view.findViewById(R.id.urlList); 48 | whitelistUrlEditText = view.findViewById(R.id.whitelistUrlEditText); 49 | 50 | appDatabase.whiteUrlDao().getAll().observe(this, whitelistUrls -> { 51 | whitelist.clear(); 52 | if (whitelistUrls != null) { 53 | for (WhiteUrl whiteUrl : whitelistUrls) { 54 | whitelist.add(whiteUrl.url); 55 | } 56 | } 57 | itemsAdapter = new ArrayAdapter<>(this.getActivity(), android.R.layout.simple_list_item_1, whitelist); 58 | whiteUrlListView.setAdapter(itemsAdapter); 59 | }); 60 | 61 | whiteUrlListView.setOnItemClickListener((parent, view1, position, id) -> { 62 | String item = (String) parent.getItemAtPosition(position); 63 | AsyncTask.execute(() -> appDatabase.whiteUrlDao().deleteByUrl(item)); 64 | itemsAdapter.notifyDataSetChanged(); 65 | Toast.makeText(this.getContext(), "Url removed", Toast.LENGTH_SHORT).show(); 66 | }); 67 | addWhitelistUrl.setOnClickListener(v -> { 68 | String urlToAdd = whitelistUrlEditText.getText().toString(); 69 | if (urlToAdd.indexOf('|') == -1) { 70 | if (!BlockUrlPatternsMatch.isUrlValid(urlToAdd)) { 71 | Toast.makeText(this.getContext(), "Url not valid. Please check", Toast.LENGTH_SHORT).show(); 72 | return; 73 | } 74 | } else { 75 | // packageName|url 76 | StringTokenizer tokens = new StringTokenizer(urlToAdd, "|"); 77 | if (tokens.countTokens() != 2) { 78 | Toast.makeText(this.getContext(), "Rule not valid. Please check", Toast.LENGTH_SHORT).show(); 79 | return; 80 | } 81 | } 82 | 83 | AsyncTask.execute(() -> { 84 | WhiteUrl whiteUrl = new WhiteUrl(urlToAdd); 85 | appDatabase.whiteUrlDao().insert(whiteUrl); 86 | }); 87 | whitelistUrlEditText.setText(""); 88 | Toast.makeText(this.getContext(), "Url has been added", Toast.LENGTH_SHORT).show(); 89 | }); 90 | return view; 91 | } 92 | 93 | @Override 94 | public void onPause() { 95 | super.onPause(); 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/model/AndroidDeviceForm.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.model; 2 | 3 | 4 | public class AndroidDeviceForm { 5 | public String deviceModel; 6 | public String deviceManufacturer; 7 | public String releaseVersion; 8 | public Integer sdkVersion; 9 | public String knoxStandardSdkVersion; 10 | public Integer adhellIntVersion; 11 | public String appId; 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/model/BillingModel.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.model; 2 | 3 | import android.arch.lifecycle.MutableLiveData; 4 | 5 | public class BillingModel { 6 | public MutableLiveData isSupportedLiveData; 7 | public MutableLiveData isPremiumLiveData; 8 | public MutableLiveData priceLiveData; 9 | public MutableLiveData threeMonthPriceLiveData; 10 | 11 | public BillingModel() { 12 | isSupportedLiveData = new MutableLiveData<>(); 13 | isPremiumLiveData = new MutableLiveData<>(); 14 | priceLiveData = new MutableLiveData<>(); 15 | threeMonthPriceLiveData = new MutableLiveData<>(); 16 | isSupportedLiveData.postValue(false); 17 | isPremiumLiveData.postValue(false); 18 | priceLiveData.postValue(""); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/net/AdhellInfoResponse.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.net; 2 | 3 | public class AdhellInfoResponse { 4 | public String appDownloadLink; 5 | public Integer appVersion; 6 | } 7 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/net/CustomResponse.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.net; 2 | 3 | 4 | public class CustomResponse { 5 | public int error; 6 | public String message; 7 | public T data; 8 | 9 | public CustomResponse() { 10 | } 11 | 12 | public CustomResponse(int error, String message, T data) { 13 | this.error = error; 14 | this.message = message; 15 | this.data = data; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/receiver/ApplicationsListChangedReceiver.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.receiver; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.net.Uri; 7 | import android.os.AsyncTask; 8 | 9 | import com.fusionjack.adhell3.App; 10 | import com.fusionjack.adhell3.db.AppDatabase; 11 | import com.fusionjack.adhell3.db.entity.AppInfo; 12 | import com.fusionjack.adhell3.utils.AppsListDBInitializer; 13 | 14 | import java.util.List; 15 | 16 | public class ApplicationsListChangedReceiver extends BroadcastReceiver { 17 | 18 | @Override 19 | public void onReceive(Context context, Intent intent) { 20 | AsyncTask.execute(() -> 21 | { 22 | AppDatabase appDatabase = AppDatabase.getAppDatabase(App.get().getApplicationContext()); 23 | List packageList = appDatabase.applicationInfoDao().getAll(); 24 | if (packageList.size() == 0) { 25 | return; 26 | } 27 | 28 | Uri data = intent.getData(); 29 | String packageName = ""; 30 | if (data != null) { 31 | packageName = data.getEncodedSchemeSpecificPart(); 32 | } 33 | 34 | String action = intent.getAction(); 35 | if (action != null && !packageName.isEmpty()) { 36 | if (action.equalsIgnoreCase("android.intent.action.PACKAGE_ADDED")) { 37 | appDatabase.applicationInfoDao().deleteAppInfoByPackageName(packageName); 38 | appDatabase.applicationInfoDao().insert(AppsListDBInitializer.getInstance() 39 | .generateAppInfo(context.getPackageManager(), packageName)); 40 | } else if (action.equalsIgnoreCase("android.intent.action.PACKAGE_REMOVED")) { 41 | appDatabase.applicationInfoDao().deleteAppInfoByPackageName(packageName); 42 | } 43 | } 44 | }); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/receiver/CustomDeviceAdminReceiver.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.receiver; 2 | 3 | import android.app.admin.DeviceAdminReceiver; 4 | 5 | public class CustomDeviceAdminReceiver extends DeviceAdminReceiver { 6 | } 7 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/utils/AppsListDBInitializer.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.utils; 2 | 3 | import android.content.pm.ApplicationInfo; 4 | import android.content.pm.PackageManager; 5 | 6 | import com.fusionjack.adhell3.App; 7 | import com.fusionjack.adhell3.db.AppDatabase; 8 | import com.fusionjack.adhell3.db.entity.AppInfo; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | import javax.inject.Inject; 14 | 15 | public class AppsListDBInitializer { 16 | private static AppsListDBInitializer instance; 17 | 18 | @Inject 19 | AppDatabase appDatabase; 20 | 21 | private AppsListDBInitializer() { 22 | App.get().getAppComponent().inject(this); 23 | } 24 | 25 | public static AppsListDBInitializer getInstance() { 26 | if (instance == null) { 27 | instance = new AppsListDBInitializer(); 28 | } 29 | return instance; 30 | } 31 | 32 | public void fillPackageDb(PackageManager packageManager) { 33 | List appsInfo = new ArrayList<>(); 34 | long id = 0; 35 | String pckg = App.get().getApplicationContext().getPackageName(); 36 | int mask = ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 37 | 38 | List applicationsInfo = packageManager.getInstalledApplications(PackageManager.GET_META_DATA); 39 | for (ApplicationInfo applicationInfo : applicationsInfo) { 40 | if (applicationInfo.packageName.equals(pckg)) { 41 | continue; 42 | } 43 | 44 | AppInfo appInfo = new AppInfo(); 45 | appInfo.id = id++; 46 | appInfo.appName = packageManager.getApplicationLabel(applicationInfo).toString(); 47 | appInfo.packageName = applicationInfo.packageName; 48 | appInfo.system = (applicationInfo.flags & mask) != 000; 49 | try { 50 | appInfo.installTime = packageManager.getPackageInfo(applicationInfo.packageName, 0).firstInstallTime; 51 | } catch (PackageManager.NameNotFoundException e) { 52 | e.printStackTrace(); 53 | appInfo.installTime = 0; 54 | } 55 | appsInfo.add(appInfo); 56 | } 57 | appDatabase.applicationInfoDao().insertAll(appsInfo); 58 | } 59 | 60 | public AppInfo generateAppInfo(PackageManager packageManager, String packageName) { 61 | AppInfo appInfo = new AppInfo(); 62 | try { 63 | ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA); 64 | appInfo.id = appDatabase.applicationInfoDao().getMaxId() + 1; 65 | appInfo.packageName = packageName; 66 | appInfo.appName = packageManager.getApplicationLabel(applicationInfo).toString(); 67 | int mask = ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 68 | appInfo.system = (applicationInfo.flags & mask) != 0; 69 | appInfo.installTime = packageManager.getPackageInfo(packageName, 0).firstInstallTime; 70 | } catch (Exception e) { 71 | e.printStackTrace(); 72 | } 73 | return appInfo; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/utils/BlockUrlPatternsMatch.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.utils; 2 | 3 | /** 4 | * Created by Matt on 19/01/2018. 5 | */ 6 | 7 | import java.util.regex.Pattern; 8 | 9 | public final class BlockUrlPatternsMatch { 10 | 11 | private static final String WILDCARD_PATTERN = "(?i)^([*])([A-Z0-9-_.]+)$|^([A-Z0-9-_.]+)([*])$|^([*])([A-Z0-9-_.]+)([*])$"; 12 | private static final Pattern wilcard_r = Pattern.compile(WILDCARD_PATTERN); 13 | 14 | private static final String DOMAIN_PATTERN = "(?i)(?=^.{4,253}$)(^((?!-)[a-z0-9-]{1,63}(?> appInfos; 36 | 37 | public AdhellWhitelistAppsViewModel(Application application) { 38 | super(application); 39 | App.get().getAppComponent().inject(this); 40 | } 41 | 42 | public LiveData> getSortedAppInfo() { 43 | if (appInfos == null) { 44 | appInfos = new MutableLiveData<>(); 45 | loadAppInfos(); 46 | } 47 | return appInfos; 48 | } 49 | 50 | private void loadAppInfos() { 51 | appInfos = mAppDatabase.applicationInfoDao().getAllSortedByWhitelist(); 52 | } 53 | 54 | public void toggleApp(AppInfo appInfo) { 55 | Maybe.fromCallable(() -> { 56 | appInfo.adhellWhitelisted = !appInfo.adhellWhitelisted; 57 | mAppDatabase.applicationInfoDao().update(appInfo); 58 | 59 | 60 | List rules = new ArrayList<>(); 61 | List superAllow = new ArrayList<>(); 62 | superAllow.add("*"); 63 | rules.add(new DomainFilterRule(new AppIdentity(appInfo.packageName, null), new ArrayList<>(), superAllow)); 64 | try { 65 | if (firewall == null || !firewall.isFirewallEnabled()) { 66 | return null; 67 | } 68 | FirewallResponse[] response = null; 69 | // TODO: Check if firewall exists 70 | if (appInfo.adhellWhitelisted) { 71 | // add allow rule 72 | response = firewall.addDomainFilterRules(rules); 73 | // response[0].getResult() 74 | } else { 75 | // remove allow rule 76 | response = firewall.removeDomainFilterRules(rules); 77 | } 78 | if (response[0].getResult() == FirewallResponse.Result.SUCCESS) { 79 | Log.d(TAG, "Firewall app rules whitelist updated successfully"); 80 | } 81 | } catch (Exception e) { 82 | Log.e(TAG, "Failed to remove filter rule"); 83 | } 84 | return null; 85 | }) 86 | .subscribeOn(Schedulers.io()) 87 | .observeOn(AndroidSchedulers.mainThread()) 88 | .subscribe(); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/viewmodel/AppPermissionsViewModel.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.viewmodel; 2 | 3 | import android.app.Application; 4 | import android.arch.lifecycle.AndroidViewModel; 5 | 6 | import com.fusionjack.adhell3.db.AppDatabase; 7 | 8 | import java.util.List; 9 | 10 | public class AppPermissionsViewModel extends AndroidViewModel { 11 | private AppDatabase mAppDatabase; 12 | private List permissions; 13 | 14 | public AppPermissionsViewModel(Application application) { 15 | super(application); 16 | mAppDatabase = AppDatabase.getAppDatabase(application); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/viewmodel/BlockUrlProvidersViewModel.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.viewmodel; 2 | 3 | import android.arch.lifecycle.LiveData; 4 | import android.arch.lifecycle.MutableLiveData; 5 | import android.arch.lifecycle.ViewModel; 6 | 7 | import com.fusionjack.adhell3.App; 8 | import com.fusionjack.adhell3.db.AppDatabase; 9 | import com.fusionjack.adhell3.db.entity.BlockUrlProvider; 10 | 11 | import java.util.List; 12 | 13 | public class BlockUrlProvidersViewModel extends ViewModel { 14 | private LiveData> blockUrlProviders; 15 | private AppDatabase mDb; 16 | 17 | public BlockUrlProvidersViewModel() { 18 | mDb = AppDatabase.getAppDatabase(App.get().getApplicationContext()); 19 | } 20 | 21 | public LiveData> getBlockUrlProviders() { 22 | if (blockUrlProviders == null) { 23 | blockUrlProviders = new MutableLiveData<>(); 24 | loadBlockUrlProviders(); 25 | } 26 | return blockUrlProviders; 27 | } 28 | 29 | private void loadBlockUrlProviders() { 30 | blockUrlProviders = mDb.blockUrlProviderDao().getAll(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/viewmodel/ProfileViewModel.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.viewmodel; 2 | 3 | 4 | import android.arch.lifecycle.LiveData; 5 | import android.arch.lifecycle.MutableLiveData; 6 | import android.arch.lifecycle.ViewModel; 7 | 8 | import com.fusionjack.adhell3.db.entity.PolicyPackage; 9 | 10 | public class ProfileViewModel extends ViewModel { 11 | private MutableLiveData policyPackagesLiveData; 12 | 13 | public LiveData getPolicyPackagesLiveData() { 14 | if (policyPackagesLiveData == null) { 15 | policyPackagesLiveData = new MutableLiveData<>(); 16 | loadPolicyPackages(); 17 | } 18 | return policyPackagesLiveData; 19 | } 20 | 21 | private void loadPolicyPackages() { 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/fusionjack/adhell3/viewmodel/SharedAppPermissionViewModel.java: -------------------------------------------------------------------------------- 1 | package com.fusionjack.adhell3.viewmodel; 2 | 3 | 4 | import android.arch.lifecycle.LiveData; 5 | import android.arch.lifecycle.MutableLiveData; 6 | import android.arch.lifecycle.ViewModel; 7 | import android.content.pm.PackageManager; 8 | 9 | import com.fusionjack.adhell3.App; 10 | import com.fusionjack.adhell3.db.AppDatabase; 11 | import com.fusionjack.adhell3.model.AdhellPermissionInfo; 12 | 13 | import javax.inject.Inject; 14 | 15 | public class SharedAppPermissionViewModel extends ViewModel { 16 | private final MutableLiveData selected = new MutableLiveData<>(); 17 | 18 | @Inject 19 | AppDatabase appDatabase; 20 | 21 | @Inject 22 | PackageManager packageManager; 23 | 24 | public SharedAppPermissionViewModel() { 25 | App.get().getAppComponent().inject(this); 26 | } 27 | 28 | public void select(AdhellPermissionInfo adhellPermissionInfo) { 29 | selected.setValue(adhellPermissionInfo); 30 | } 31 | 32 | public LiveData getSelected() { 33 | return selected; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/res/animator/enter_from_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/animator/enter_from_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/animator/exit_to_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/animator/exit_to_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_check_box_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-hdpi/ic_check_box_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_check_box_outline_blank_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-hdpi/ic_check_box_outline_blank_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_delete_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-hdpi/ic_delete_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_home_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-hdpi/ic_home_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_lock_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-hdpi/ic_lock_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_question_answer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-hdpi/ic_question_answer.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_settings_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-hdpi/ic_settings_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_signal_cellular_no_sim_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-hdpi/ic_signal_cellular_no_sim_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_sort_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-hdpi/ic_sort_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_visibility_off_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-hdpi/ic_visibility_off_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/overflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-hdpi/overflow.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_check_box_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-mdpi/ic_check_box_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_check_box_outline_blank_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-mdpi/ic_check_box_outline_blank_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_delete_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-mdpi/ic_delete_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_home_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-mdpi/ic_home_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_lock_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-mdpi/ic_lock_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_question_answer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-mdpi/ic_question_answer.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_settings_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-mdpi/ic_settings_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_signal_cellular_no_sim_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-mdpi/ic_signal_cellular_no_sim_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_sort_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-mdpi/ic_sort_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_visibility_off_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-mdpi/ic_visibility_off_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/overflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-mdpi/overflow.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_check_box_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xhdpi/ic_check_box_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_check_box_outline_blank_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xhdpi/ic_check_box_outline_blank_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_delete_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xhdpi/ic_delete_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_home_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xhdpi/ic_home_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_lock_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xhdpi/ic_lock_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_question_answer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xhdpi/ic_question_answer.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_settings_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xhdpi/ic_settings_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_signal_cellular_no_sim_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xhdpi/ic_signal_cellular_no_sim_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_sort_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xhdpi/ic_sort_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_visibility_off_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xhdpi/ic_visibility_off_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/overflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xhdpi/overflow.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_check_box_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xxhdpi/ic_check_box_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_check_box_outline_blank_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xxhdpi/ic_check_box_outline_blank_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_delete_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xxhdpi/ic_delete_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_home_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xxhdpi/ic_home_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_lock_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xxhdpi/ic_lock_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_question_answer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xxhdpi/ic_question_answer.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_settings_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xxhdpi/ic_settings_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_signal_cellular_no_sim_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xxhdpi/ic_signal_cellular_no_sim_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_sort_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xxhdpi/ic_sort_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_visibility_off_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xxhdpi/ic_visibility_off_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/overflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xxhdpi/overflow.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_check_box_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xxxhdpi/ic_check_box_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_check_box_outline_blank_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xxxhdpi/ic_check_box_outline_blank_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_delete_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xxxhdpi/ic_delete_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_home_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xxxhdpi/ic_home_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_lock_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xxxhdpi/ic_lock_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_question_answer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xxxhdpi/ic_question_answer.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_settings_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xxxhdpi/ic_settings_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_signal_cellular_no_sim_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xxxhdpi/ic_signal_cellular_no_sim_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_sort_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xxxhdpi/ic_sort_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_visibility_off_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xxxhdpi/ic_visibility_off_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/overflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ngerstle/Adhell3/a3bccd12f2fbef4de5081b35ef4e57fa6a9adefd/app/src/main/res/drawable-xxxhdpi/overflow.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/checkbox.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 8 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 20 | 21 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/layout/card_profile.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 15 | 16 | 19 | 20 | 29 | 35 | 45 | 52 | 59 | 66 | 73 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /app/src/main/res/layout/checkbox.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 8 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_dns.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 14 | 15 | 24 | 25 | 26 | 27 | 28 | 37 | 38 | 44 |