package com.ichi2.compat;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.net.Uri;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebSettings;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RemoteViews;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.ichi2.anki.AbstractFlashcardViewer;
import com.ichi2.anki.AnkiActivity;
import com.ichi2.anki.AnkiDroidApp;
import com.ichi2.anki.CollectionHelper;
import com.ichi2.anki.DeckPicker;
import com.ichi2.anki.Preferences;
import com.ichi2.anki.R;
import com.ichi2.anki.ReadText;
import com.ichi2.compat.customtabs.CustomTabsFallback;
import java.io.File;
import io.requery.android.database.sqlite.SQLiteDatabase;
import timber.log.Timber;
/** Implementation of {@link Compat} for SDK level 7 */
@TargetApi(10)
public class CompatV10 implements Compat {
protected static final int FULLSCREEN_ALL_GONE = 2;
/*
* Return the input string in a form suitable for display on a HTML page. Replace “<”, “>”, “&”, “"” and “'” with
* HTML entities.
*
* @param txt Text to be cleaned.
* @return The input text, with HTML tags and entities escaped.
*/
public String detagged(String txt) {
if (txt == null) {
return "";
}
return txt.replace("&", "&").replace("<", "<").replace(">", ">").replace("\"", """).replace(
"'", "'");
}
public void setTtsOnUtteranceProgressListener(TextToSpeech tts) {
tts.setOnUtteranceCompletedListener(new OnUtteranceCompletedListener() {
@Override
public void onUtteranceCompleted(String utteranceId) {
if (ReadText.sTextQueue.size() > 0) {
String[] text = ReadText.sTextQueue.remove(0);
ReadText.speak(text[0], text[1]);
}
}
});
}
public void disableDatabaseWriteAheadLogging(SQLiteDatabase db) {
// We've never used WAL mode on Gingerbread so don't need to do anything here
}
// Below API level 12, file scheme pages are not restricted, so no adjustment is needed.
public void enableCookiesForFileSchemePages() {
Timber.w("Cookies not supported in API version %d", CompatHelper.getSdkVersion());
}
// CookieSyncManager is need to be initialized before use.
// Note: CookieSyncManager is deprecated since API level 21, but still need to be used here.
public void prepareWebViewCookies(Context context) {
CookieSyncManager.createInstance(context);
}
// A data of cookies may be lost when an application exists just after it was written.
// Below API level 21, this problem can be solved by using CookieSyncManager.sync().
// Note: CookieSyncManager is deprecated since API level 21, but still need to be used here.
public void flushWebViewCookies() {
CookieSyncManager.getInstance().sync();
}
// Below API level 17, there is no simple way to enable the auto play feature of HTML media elements.
public void setHTML5MediaAutoPlay(WebSettings webSettings, Boolean allow) {
}
// Below API level 16, widget dimensions cannot be adjusted
public void updateWidgetDimensions(Context context, RemoteViews updateViews, Class<?> cls) {
}
/**
* Pre-honeycomb just completely boot back to the DeckPicker
*/
public void restartActivityInvalidateBackstack(AnkiActivity activity) {
Timber.i("AnkiActivity -- restartActivityInvalidateBackstack()");
//TODO: Find a way to recreate the backstack even pre-Honeycomb
Intent intent = new Intent(activity, DeckPicker.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
activity.startActivityWithoutAnimation(intent);
}
public void setFullScreen(AbstractFlashcardViewer a) {
a.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
final int fullscreenMode = Integer.parseInt(AnkiDroidApp.getSharedPrefs(a).getString("fullscreenMode", "0"));
if (fullscreenMode >= FULLSCREEN_ALL_GONE) {
final LinearLayout answerButtons = (LinearLayout) a.findViewById(R.id.answer_options_layout);
answerButtons.setVisibility(View.GONE);
}
}
public void setSelectableBackground(View view) {
// NOTE: we can't use android.R.attr.selectableItemBackground until API 11
Context context = view.getContext();
int[] attrs = new int[] {android.R.attr.colorBackground};
TypedArray ta = context.obtainStyledAttributes(attrs);
view.setBackgroundColor(ta.getColor(0, ContextCompat.getColor(context, R.color.white)));
ta.recycle();
}
public void openUrl(AnkiActivity activity, Uri uri) {
new CustomTabsFallback().openUri(activity, uri);
}
/**
* FloatingActionsMenu has a bug on Android 2.3 where the collapsed menu items can still be clicked,
* so we revert to showing a ContextMenu below API 14.
* @param activity DeckPicker instance that we can run callbacks on
*/
public void supportAddContentMenu(final DeckPicker activity) {
Resources res = activity.getResources();
new MaterialDialog.Builder(activity)
.items(new String[]{res.getString(R.string.menu_add_note),
res.getString(R.string.menu_get_shared_decks),
res.getString(R.string.new_deck)})
.itemsCallback(new MaterialDialog.ListCallback() {
@Override
public void onSelection(MaterialDialog materialDialog, View view, int i,
CharSequence charSequence) {
switch (i) {
case 0:
activity.addNote();
break;
case 1:
activity.addSharedDeck();
break;
case 2:
final EditText mDialogEditText = new EditText(activity);
mDialogEditText.setSingleLine(true);
new MaterialDialog.Builder(activity)
.title(R.string.new_deck)
.positiveText(R.string.dialog_ok)
.customView(mDialogEditText, true)
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog d, @NonNull DialogAction w) {
Timber.i("DeckPicker:: Creating new deck...");
String deckName = mDialogEditText.getText().toString();
activity.getCol().getDecks().id(deckName, true);
activity.onRequireDeckListUpdate();
}
})
.negativeText(R.string.dialog_cancel)
.show();
}
}
})
.build().show();
}
@Override
public Intent getPreferenceSubscreenIntent(Context context, String subscreen) {
// We're using "legacy preference headers" below API 11
Intent i = new Intent(context, Preferences.class);
i.setAction(subscreen);
return i;
}
@Override
public void setStatusBarColor(Window window, int color) {
// Not settable before API 21 so do nothing
}
@Override
public boolean isImmersiveSystemUiVisible(AnkiActivity activity) {
return false; // Immersive mode introduced in KitKat
}
@Override
public boolean deleteDatabase(File db) {
return db.delete();
}
@Override
public Uri getExportUri(Context context, File file) {
return Uri.fromFile(file);
}
}