/*******************************************************************************
* This file is part of RedReader.
*
* RedReader 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
* (at your option) any later version.
*
* RedReader 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 RedReader. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package org.quantumbadger.redreader.activities;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.TypedArray;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import org.quantumbadger.redreader.R;
import org.quantumbadger.redreader.common.General;
import org.quantumbadger.redreader.common.PrefsUtility;
import org.quantumbadger.redreader.common.TorCommon;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicInteger;
public abstract class BaseActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
private SharedPreferences mSharedPreferences;
private static boolean closingAll = false;
private final AtomicInteger mPermissionRequestIdGenerator = new AtomicInteger();
private final HashMap<Integer, PermissionCallback> mPermissionRequestCallbacks = new HashMap<>();
private TextView mActionbarTitleTextView;
private FrameLayout mContentView;
private ImageView mActionbarBackIconView;
private View mActionbarTitleOuterView;
protected boolean baseActivityIsToolbarActionBarEnabled() {
return true;
}
protected boolean baseActivityIsActionBarBackEnabled() {
return true;
}
@Override
public void setTitle(final CharSequence text) {
super.setTitle(text);
if(mActionbarTitleTextView != null) {
mActionbarTitleTextView.setText(text);
}
}
@Override
public void setTitle(final int res) {
setTitle(getText(res));
}
public interface PermissionCallback {
void onPermissionGranted();
void onPermissionDenied();
}
public void closeAllExceptMain() {
closingAll = true;
closeIfNecessary();
}
// Avoids IDE warnings about null pointers
@NonNull
public final ActionBar getSupportActionBarOrThrow() {
final ActionBar result = getSupportActionBar();
if(result == null) {
throw new RuntimeException("Action bar is null");
}
return result;
}
protected void configBackButton(boolean isVisible, View.OnClickListener listener) {
if(isVisible) {
mActionbarBackIconView.setVisibility(View.VISIBLE);
mActionbarTitleOuterView.setOnClickListener(listener);
mActionbarTitleOuterView.setClickable(true);
} else {
mActionbarBackIconView.setVisibility(View.GONE);
mActionbarTitleOuterView.setClickable(false);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
if(PrefsUtility.pref_appearance_hide_android_status(this, mSharedPreferences)) {
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
mSharedPreferences.registerOnSharedPreferenceChangeListener(this);
setOrientationFromPrefs();
closeIfNecessary();
if(baseActivityIsToolbarActionBarEnabled()) {
final View outerView = getLayoutInflater().inflate(R.layout.rr_actionbar, null);
final Toolbar toolbar = (Toolbar) outerView.findViewById(R.id.rr_actionbar_toolbar);
mContentView = (FrameLayout) outerView.findViewById(R.id.rr_actionbar_content);
super.setContentView(outerView);
setSupportActionBar(toolbar);
getSupportActionBarOrThrow().setCustomView(R.layout.actionbar_title);
getSupportActionBarOrThrow().setDisplayShowCustomEnabled(true);
getSupportActionBarOrThrow().setDisplayShowTitleEnabled(false);
toolbar.setContentInsetsAbsolute(0, 0);
mActionbarTitleTextView = (TextView)toolbar.findViewById(R.id.actionbar_title_text);
mActionbarBackIconView = (ImageView)toolbar.findViewById(R.id.actionbar_title_back_image);
mActionbarTitleOuterView = toolbar.findViewById(R.id.actionbar_title_outer);
if(getTitle() != null) {
// Update custom action bar text
setTitle(getTitle());
}
configBackButton(baseActivityIsActionBarBackEnabled(), new View.OnClickListener() {
@Override
public void onClick(final View v) {
finish();
}
});
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
final PrefsUtility.AppearanceNavbarColour navbarColour = PrefsUtility.appearance_navbar_colour(
this,
mSharedPreferences);
if(navbarColour != PrefsUtility.AppearanceNavbarColour.BLACK) {
final int colour;
{
final TypedArray appearance = obtainStyledAttributes(new int[]{
R.attr.colorPrimary,
R.attr.colorPrimaryDark});
if(navbarColour == PrefsUtility.AppearanceNavbarColour.PRIMARY) {
colour = appearance.getColor(0, General.COLOR_INVALID);
} else {
colour = appearance.getColor(1, General.COLOR_INVALID);
}
appearance.recycle();
}
getWindow().setNavigationBarColor(colour);
}
}
}
}
public void setBaseActivityContentView(@LayoutRes int layoutResID) {
if(mContentView != null) {
mContentView.removeAllViews();
getLayoutInflater().inflate(layoutResID, mContentView, true);
} else {
super.setContentView(layoutResID);
}
}
public void setBaseActivityContentView(@NonNull final View view) {
if(mContentView != null) {
mContentView.removeAllViews();
mContentView.addView(view);
} else {
super.setContentView(view);
}
}
@Override
protected void onResume() {
super.onResume();
setOrientationFromPrefs();
closeIfNecessary();
TorCommon.updateTorStatus(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
mSharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
}
private void closeIfNecessary() {
if(closingAll) {
if(this instanceof MainActivity) {
closingAll = false;
} else {
finish();
}
}
}
public void requestPermissionWithCallback(
@NonNull final String permission,
@NonNull final PermissionCallback callback) {
General.checkThisIsUIThread();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED) {
callback.onPermissionGranted();
} else {
final int requestCode = mPermissionRequestIdGenerator.incrementAndGet();
mPermissionRequestCallbacks.put(requestCode, callback);
requestPermissions(new String[]{permission}, requestCode);
}
} else {
callback.onPermissionGranted();
}
}
@Override
public void onRequestPermissionsResult(
final int requestCode,
@NonNull final String[] permissions,
@NonNull final int[] grantResults) {
final PermissionCallback callback = mPermissionRequestCallbacks.remove(requestCode);
if(callback != null) {
if(permissions.length != 1) {
throw new RuntimeException("Unexpected permission result");
}
if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
callback.onPermissionGranted();
} else {
callback.onPermissionDenied();
}
}
}
private void setOrientationFromPrefs() {
PrefsUtility.ScreenOrientation orientation = PrefsUtility.pref_behaviour_screen_orientation(this,
mSharedPreferences);
if (orientation == PrefsUtility.ScreenOrientation.AUTO)
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
else if (orientation == PrefsUtility.ScreenOrientation.PORTRAIT)
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
else if (orientation == PrefsUtility.ScreenOrientation.LANDSCAPE)
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
protected void onSharedPreferenceChangedInner(final SharedPreferences prefs, final String key) {
// Do nothing
}
@Override
public final void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
onSharedPreferenceChangedInner(prefs, key);
if(key.equals(getString(R.string.pref_menus_optionsmenu_items_key))) {
invalidateOptionsMenu();
}
}
}