/* * MaxLock, an Xposed applock module for Android * Copyright (C) 2014-2016 Max Rumpf alias Maxr1998 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.Maxr1998.xposed.maxlock.ui; import android.annotation.SuppressLint; import android.app.admin.DeviceAdminReceiver; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.os.Build; import android.os.Bundle; import android.preference.PreferenceManager; import android.support.annotation.Nullable; import android.support.customtabs.CustomTabsCallback; import android.support.customtabs.CustomTabsClient; import android.support.customtabs.CustomTabsIntent; import android.support.customtabs.CustomTabsService; import android.support.customtabs.CustomTabsServiceConnection; import android.support.customtabs.CustomTabsSession; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.content.ContextCompat; import android.support.v4.view.MenuItemCompat; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatDelegate; import android.support.v7.widget.SwitchCompat; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import java.util.Arrays; import de.Maxr1998.xposed.maxlock.BuildConfig; import de.Maxr1998.xposed.maxlock.Common; import de.Maxr1998.xposed.maxlock.MLImplementation; import de.Maxr1998.xposed.maxlock.R; import de.Maxr1998.xposed.maxlock.lib.StatusBarTintApi; import de.Maxr1998.xposed.maxlock.ui.firstStart.FirstStartActivity; import de.Maxr1998.xposed.maxlock.ui.lockscreen.LockView; import de.Maxr1998.xposed.maxlock.ui.settings.MaxLockPreferenceFragment; import de.Maxr1998.xposed.maxlock.ui.settings.Startup; import de.Maxr1998.xposed.maxlock.ui.settings.applist.AppListFragment; import de.Maxr1998.xposed.maxlock.util.AuthenticationSucceededListener; import de.Maxr1998.xposed.maxlock.util.MLPreferences; import de.Maxr1998.xposed.maxlock.util.Util; import static de.Maxr1998.xposed.maxlock.util.Util.LOG_TAG_ADMIN; public class SettingsActivity extends AppCompatActivity implements AuthenticationSucceededListener { private static final String TAG_PREFERENCE_FRAGMENT = "MLPreferenceFragment"; private static final String TAG_PREFERENCE_FRAGMENT_SECOND_PANE = "SecondPanePreferenceFragment"; private static final String TAG_LOCK_FRAGMENT = "LockFragment"; private static boolean UNLOCKED = false; static { AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); } public ComponentName deviceAdmin; private Fragment mSettingsFragment; private DevicePolicyManager devicePolicyManager; private CustomTabsServiceConnection mConnection; private CustomTabsSession mSession; public static boolean isSecondPane(Fragment f) { return f.getTag() != null && f.getTag().equals(TAG_PREFERENCE_FRAGMENT_SECOND_PANE); } /** * Show second pane if available */ public static void showMultipane(FragmentManager manager) { Fragment secondPane = manager.findFragmentByTag(TAG_PREFERENCE_FRAGMENT_SECOND_PANE); if (secondPane != null) { manager.beginTransaction().show(secondPane).commit(); } } /** * Hide second pane if visible */ public static void hideMultipane(FragmentManager manager) { Fragment secondPane = manager.findFragmentByTag(TAG_PREFERENCE_FRAGMENT_SECOND_PANE); if (secondPane != null) { manager.beginTransaction().hide(secondPane).commit(); } } @Override protected void onCreate(Bundle savedInstanceState) { Util.setTheme(this); super.onCreate(savedInstanceState); if (MLPreferences.getPreferences(this).getInt(FirstStartActivity.FIRST_START_LAST_VERSION_KEY, 0) != FirstStartActivity.FIRST_START_LATEST_VERSION) { startActivity(new Intent(this, FirstStartActivity.class)); } devicePolicyManager = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE); deviceAdmin = new ComponentName(this, UninstallProtectionReceiver.class); setContentView(R.layout.activity_settings); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); // Hide multipane view if (getSupportFragmentManager().getBackStackEntryCount() == 0) { hideMultipane(getSupportFragmentManager()); } mSettingsFragment = getSupportFragmentManager().findFragmentByTag(TAG_PREFERENCE_FRAGMENT); if (mSettingsFragment == null) { // Main fragment not visible → app just opened if (getSupportFragmentManager().findFragmentByTag(TAG_LOCK_FRAGMENT) == null) { // Lockscreen not visible as well → run startup & show lockscreen new Startup(this).execute(); UNLOCKED = false; getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new Lockscreen(), TAG_LOCK_FRAGMENT).commit(); } // Hide Action bar if (getSupportActionBar() != null) { getSupportActionBar().hide(); } } mConnection = new CustomTabsServiceConnection() { @Override public void onCustomTabsServiceConnected(ComponentName componentName, CustomTabsClient customTabsClient) { customTabsClient.warmup(0); mSession = customTabsClient.newSession(new CustomTabsCallback()); if (mSession == null) { return; } Bundle maxr1998Website = new Bundle(); maxr1998Website.putParcelable(CustomTabsService.KEY_URL, Common.MAXR1998_URI); Bundle technoSparksProfile = new Bundle(); technoSparksProfile.putParcelable(CustomTabsService.KEY_URL, Common.TECHNO_SPARKS_URI); Bundle knownProblemSettings = new Bundle(); knownProblemSettings.putParcelable(CustomTabsService.KEY_URL, Common.KNOWN_PROBLEM_SETTINGS_URI); mSession.mayLaunchUrl(Common.WEBSITE_URI, null, Arrays.asList(technoSparksProfile, maxr1998Website, knownProblemSettings)); } @Override public void onServiceDisconnected(ComponentName name) { } }; CustomTabsClient.bindCustomTabsService(this, "com.android.chrome", mConnection); } @SuppressLint("WorldReadableFiles") @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.toolbar_menu, menu); SwitchCompat master_switch = (SwitchCompat) MenuItemCompat.getActionView(menu.findItem(R.id.toolbar_master_switch)); //noinspection deprecation master_switch.setChecked(MLPreferences.getPrefsApps(this).getBoolean(Common.MASTER_SWITCH_ON, true)); master_switch.setOnCheckedChangeListener((button, b) -> MLPreferences.getPrefsApps(SettingsActivity.this).edit().putBoolean(Common.MASTER_SWITCH_ON, b).commit()); Fragment lockScreen = getSupportFragmentManager().findFragmentByTag(TAG_LOCK_FRAGMENT); if (getSupportActionBar() != null && !getSupportActionBar().isShowing() && (lockScreen == null || !lockScreen.isVisible())) { getSupportActionBar().show(); } return super.onCreateOptionsMenu(menu); } @SuppressLint("WorldReadableFiles") @Override public boolean onPrepareOptionsMenu(Menu menu) { SwitchCompat master_switch = (SwitchCompat) MenuItemCompat.getActionView(menu.findItem(R.id.toolbar_master_switch)); master_switch.setChecked(MLPreferences.getPrefsApps(SettingsActivity.this).getBoolean(Common.MASTER_SWITCH_ON, true)); return super.onPrepareOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.toolbar_info: @SuppressWarnings("deprecation") CustomTabsIntent intent = new CustomTabsIntent.Builder(mSession) .setShowTitle(true) .enableUrlBarHiding() .setToolbarColor(getResources().getColor(R.color.primary_red)) .build(); intent.launchUrl(this, Common.WEBSITE_URI); return true; case android.R.id.home: onBackPressed(); return false; default: return false; } } @Override public void onBackPressed() { if (getSupportFragmentManager().getBackStackEntryCount() > 0) { if (getSupportFragmentManager().getBackStackEntryCount() == 1) { hideMultipane(getSupportFragmentManager()); } getSupportFragmentManager().popBackStack(); } else { super.onBackPressed(); } } @Override public void onAuthenticationSucceeded() { UNLOCKED = true; if (mSettingsFragment == null) { mSettingsFragment = getIntent().getAction().equals(BuildConfig.APPLICATION_ID + ".VIEW_APPS") ? new AppListFragment() : MaxLockPreferenceFragment.Screen.MAIN.getScreen(); getSupportFragmentManager().beginTransaction() .setCustomAnimations(R.anim.fragment_in, R.anim.fragment_out) .replace(R.id.fragment_container, mSettingsFragment, TAG_PREFERENCE_FRAGMENT) .commit(); if (getSupportActionBar() != null) { getSupportActionBar().show(); } } updateXposedStatusAlert(); } public void updateXposedStatusAlert() { //noinspection ConstantConditions if (!MLImplementation.isXposedActive()) { boolean showWarning = MLImplementation.getImplementation(MLPreferences.getPreferences(this)) == MLImplementation.DEFAULT; //noinspection ConstantConditions findViewById(R.id.xposed_active).setVisibility(showWarning ? View.VISIBLE : View.GONE); //noinspection ConstantConditions findViewById(R.id.xposed_active_message).setOnClickListener(v -> { AlertDialog help = new AlertDialog.Builder(SettingsActivity.this) .setTitle(R.string.maxlock_inactive) .setMessage(R.string.dialog_message_not_active) .create(); help.show(); }); } } @Override protected void onStart() { super.onStart(); invalidateOptionsMenu(); } @Override protected void onResume() { super.onResume(); if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) { StatusBarTintApi.sendColorChangeIntent(ContextCompat.getColor(this, R.color.primary_red_dark), -3, Color.BLACK, -3, this); } } @Override protected void onPause() { super.onPause(); if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(Common.ENABLE_LOGGING, false) && !UNLOCKED) { Util.logFailedAuthentication(this, getPackageName()); } } @Override protected void onDestroy() { if (mConnection != null) { unbindService(mConnection); } super.onDestroy(); } public void restart() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(R.string.dialog_text_restart_required); builder.setTitle(R.string.app_name) .setPositiveButton(android.R.string.ok, (dialogInterface, i) -> { Intent intent = getIntent(); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); finish(); startActivity(intent); }).create().show(); } public CustomTabsSession getSession() { return mSession; } public DevicePolicyManager getDevicePolicyManager() { return devicePolicyManager; } public boolean isDeviceAdminActive() { return devicePolicyManager.isAdminActive(deviceAdmin); } public static class UninstallProtectionReceiver extends DeviceAdminReceiver { @Override public void onEnabled(Context context, Intent intent) { super.onEnabled(context, intent); Log.i(LOG_TAG_ADMIN, "Device admin is now active!"); } } @SuppressWarnings("WeakerAccess") public static class Lockscreen extends Fragment { @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return new LockView(LockView.getThemedContext(getActivity()), getActivity().getApplicationContext().getPackageName(), SettingsActivity.class.getName()); } } }