blob: 7c0cf0eebc790f9ee86e64e1869a8f2da5e04af2 [file] [log] [blame]
package android.text;
import static android.text.Spanned.SPAN_INCLUSIVE_INCLUSIVE;
import android.text.style.BulletSpan;
import java.util.Random;
/**
*
*/
public class NonEditableTextGenerator {
enum TextType {
STRING,
SPANNED,
SPANNABLE_BUILDER
}
private boolean mCreateBoring;
private TextType mTextType;
private int mSequenceLength;
private final Random mRandom;
public NonEditableTextGenerator(Random random) {
mRandom = random;
}
public NonEditableTextGenerator setCreateBoring(boolean createBoring) {
mCreateBoring = createBoring;
return this;
}
public NonEditableTextGenerator setTextType(TextType textType) {
mTextType = textType;
return this;
}
public NonEditableTextGenerator setSequenceLength(int sequenceLength) {
mSequenceLength = sequenceLength;
return this;
}
/**
* Sample charSequence generated:
* NRjPzjvUadHmH ExoEoTqfx pCLw qtndsqfpk AqajVCbgjGZ igIeC dfnXRgA
*/
public CharSequence build() {
final RandomCharSequenceGenerator sequenceGenerator = new RandomCharSequenceGenerator(
mRandom);
if (mSequenceLength > 0) {
sequenceGenerator.setSequenceLength(mSequenceLength);
}
final CharSequence charSequence = sequenceGenerator.buildLatinSequence();
switch (mTextType) {
case SPANNED:
case SPANNABLE_BUILDER:
return createSpannable(charSequence);
case STRING:
default:
return createString(charSequence);
}
}
private Spannable createSpannable(CharSequence charSequence) {
final Spannable spannable = (mTextType == TextType.SPANNABLE_BUILDER) ?
new SpannableStringBuilder(charSequence) : new SpannableString(charSequence);
if (!mCreateBoring) {
// add a paragraph style to make it non boring
spannable.setSpan(new BulletSpan(), 0, spannable.length(), SPAN_INCLUSIVE_INCLUSIVE);
}
spannable.setSpan(new Object(), 0, spannable.length(), SPAN_INCLUSIVE_INCLUSIVE);
spannable.setSpan(new Object(), 0, 1, SPAN_INCLUSIVE_INCLUSIVE);
return spannable;
}
private String createString(CharSequence charSequence) {
if (mCreateBoring) {
return charSequence.toString();
} else {
// BoringLayout checks to see if there is a surrogate pair and if so tells that
// the charSequence is not suitable for boring. Add an emoji to make it non boring.
// Emoji is added instead of RTL, since emoji stays in the same run and is a more
// common case.
return charSequence.toString() + "\uD83D\uDC68\uD83C\uDFFF";
}
}
public static class RandomCharSequenceGenerator {
private static final int DEFAULT_MIN_WORD_LENGTH = 3;
private static final int DEFAULT_MAX_WORD_LENGTH = 15;
private static final int DEFAULT_SEQUENCE_LENGTH = 256;
private int mMinWordLength = DEFAULT_MIN_WORD_LENGTH;
private int mMaxWordLength = DEFAULT_MAX_WORD_LENGTH;
private int mSequenceLength = DEFAULT_SEQUENCE_LENGTH;
private final Random mRandom;
public RandomCharSequenceGenerator(Random random) {
mRandom = random;
}
public RandomCharSequenceGenerator setSequenceLength(int sequenceLength) {
mSequenceLength = sequenceLength;
return this;
}
public CharSequence buildLatinSequence() {
final StringBuilder result = new StringBuilder();
while (result.length() < mSequenceLength) {
// add random word
result.append(buildLatinWord());
result.append(' ');
}
return result.substring(0, mSequenceLength);
}
public CharSequence buildLatinWord() {
final StringBuilder result = new StringBuilder();
// create a random length that is (mMinWordLength + random amount of chars) where
// total size is less than mMaxWordLength
final int length = mRandom.nextInt(mMaxWordLength - mMinWordLength) + mMinWordLength;
while (result.length() < length) {
// add random letter
int base = mRandom.nextInt(2) == 0 ? 'A' : 'a';
result.append(Character.toChars(mRandom.nextInt(26) + base));
}
return result.toString();
}
}
}