package org.thoughtcrime.securesms; import android.annotation.TargetApi; import android.app.ActivityManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Build; import android.os.Build.VERSION_CODES; import android.os.Bundle; import androidx.annotation.NonNull; import androidx.core.app.ActivityCompat; import androidx.core.app.ActivityOptionsCompat; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.appcompat.app.AppCompatActivity; import android.view.KeyEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.WindowManager; import android.widget.Toast; import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.dynamiclanguage.DynamicLanguageActivityHelper; import org.thoughtcrime.securesms.util.dynamiclanguage.DynamicLanguageContextWrapper; import java.lang.reflect.Field; import java.util.Date; import network.loki.messenger.R; public abstract class BaseActionBarActivity extends AppCompatActivity { private static final String TAG = BaseActionBarActivity.class.getSimpleName(); private BroadcastReceiver broadcastReceiver; private Date lastUnexpectedDeviceLinkRequestDate; @Override protected void onCreate(Bundle savedInstanceState) { if (BaseActivity.isMenuWorkaroundRequired()) { forceOverflowMenu(); } super.onCreate(savedInstanceState); } @Override protected void onResume() { super.onResume(); initializeScreenshotSecurity(); DynamicLanguageActivityHelper.recreateIfNotInCorrectLanguage(this, TextSecurePreferences.getLanguage(this)); String name = getResources().getString(R.string.app_name); Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground); int color = getResources().getColor(R.color.app_icon_background); setTaskDescription(new ActivityManager.TaskDescription(name, icon, color)); broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Date now = new Date(); if (lastUnexpectedDeviceLinkRequestDate != null) { if (now.getTime() - lastUnexpectedDeviceLinkRequestDate.getTime() < 30 * 1000) { return; } } lastUnexpectedDeviceLinkRequestDate = now; Toast.makeText(BaseActionBarActivity.this, "Open the device link screen by going to \"Settings\"> \"Devices\" > \"Link a Device\" to link your devices.", Toast.LENGTH_LONG).show(); } }; LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, new IntentFilter("unexpectedDeviceLinkRequestReceived")); } @Override protected void onDestroy() { LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver); super.onDestroy(); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { return (keyCode == KeyEvent.KEYCODE_MENU && BaseActivity.isMenuWorkaroundRequired()) || super.onKeyDown(keyCode, event); } @Override public boolean onKeyUp(int keyCode, @NonNull KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_MENU && BaseActivity.isMenuWorkaroundRequired()) { openOptionsMenu(); return true; } return super.onKeyUp(keyCode, event); } private void initializeScreenshotSecurity() { if (TextSecurePreferences.isScreenSecurityEnabled(this)) { getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); } else { getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE); } } /** * Modified from: http://stackoverflow.com/a/13098824 */ private void forceOverflowMenu() { try { ViewConfiguration config = ViewConfiguration.get(this); Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey"); if(menuKeyField != null) { menuKeyField.setAccessible(true); menuKeyField.setBoolean(config, false); } } catch (IllegalAccessException e) { Log.w(TAG, "Failed to force overflow menu."); } catch (NoSuchFieldException e) { Log.w(TAG, "Failed to force overflow menu."); } } protected void startActivitySceneTransition(Intent intent, View sharedView, String transitionName) { Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(this, sharedView, transitionName) .toBundle(); ActivityCompat.startActivity(this, intent, bundle); } //TODO AC: I don't think we need this method, // setting any colors directly will most likely clash with the current theme. @Deprecated @TargetApi(VERSION_CODES.LOLLIPOP) protected void setStatusBarColor(int color) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { getWindow().setStatusBarColor(color); } } @Override protected void attachBaseContext(Context newBase) { super.attachBaseContext(DynamicLanguageContextWrapper.updateContext(newBase, TextSecurePreferences.getLanguage(newBase))); } }