Merge "Q card." into qt-dev
am: 13de667fa6
Change-Id: I844b8a49d78988b4bf5cffbce04c9b4b4e3469ca
This commit is contained in:
@@ -16,252 +16,167 @@
|
|||||||
|
|
||||||
package com.android.internal.app;
|
package com.android.internal.app;
|
||||||
|
|
||||||
|
import android.animation.ObjectAnimator;
|
||||||
import android.animation.TimeAnimator;
|
import android.animation.TimeAnimator;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.ActivityNotFoundException;
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.res.ColorStateList;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapShader;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.ColorFilter;
|
import android.graphics.ColorFilter;
|
||||||
|
import android.graphics.Matrix;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
import android.graphics.Path;
|
||||||
|
import android.graphics.PixelFormat;
|
||||||
|
import android.graphics.Shader;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.HapticFeedbackConstants;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.MotionEvent.PointerCoords;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.FrameLayout;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import com.android.internal.R;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
public class PlatLogoActivity extends Activity {
|
public class PlatLogoActivity extends Activity {
|
||||||
FrameLayout layout;
|
ImageView mZeroView, mOneView;
|
||||||
TimeAnimator anim;
|
BackslashDrawable mBackslash;
|
||||||
PBackground bg;
|
int mClicks;
|
||||||
|
|
||||||
private class PBackground extends Drawable {
|
static final Paint sPaint = new Paint();
|
||||||
private float maxRadius, radius, x, y, dp;
|
static {
|
||||||
private int[] palette;
|
sPaint.setStyle(Paint.Style.STROKE);
|
||||||
private int darkest;
|
sPaint.setStrokeWidth(4f);
|
||||||
private float offset;
|
sPaint.setStrokeCap(Paint.Cap.SQUARE);
|
||||||
|
|
||||||
public PBackground() {
|
|
||||||
randomizePalette();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* set inner radius of "p" logo
|
|
||||||
*/
|
|
||||||
public void setRadius(float r) {
|
|
||||||
this.radius = Math.max(48*dp, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* move the "p"
|
|
||||||
*/
|
|
||||||
public void setPosition(float x, float y) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* for animating the "p"
|
|
||||||
*/
|
|
||||||
public void setOffset(float o) {
|
|
||||||
this.offset = o;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* rough luminance calculation
|
|
||||||
* https://www.w3.org/TR/AERT/#color-contrast
|
|
||||||
*/
|
|
||||||
public float lum(int rgb) {
|
|
||||||
return ((Color.red(rgb) * 299f) + (Color.green(rgb) * 587f) + (Color.blue(rgb) * 114f)) / 1000f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* create a random evenly-spaced color palette
|
|
||||||
* guaranteed to contrast!
|
|
||||||
*/
|
|
||||||
public void randomizePalette() {
|
|
||||||
final int slots = 2 + (int)(Math.random() * 2);
|
|
||||||
float[] color = new float[] { (float) Math.random() * 360f, 1f, 1f };
|
|
||||||
palette = new int[slots];
|
|
||||||
darkest = 0;
|
|
||||||
for (int i=0; i<slots; i++) {
|
|
||||||
palette[i] = Color.HSVToColor(color);
|
|
||||||
color[0] = (color[0] + 360f/slots) % 360f;
|
|
||||||
if (lum(palette[i]) < lum(palette[darkest])) darkest = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
final StringBuilder str = new StringBuilder();
|
|
||||||
for (int c : palette) {
|
|
||||||
str.append(String.format("#%08x ", c));
|
|
||||||
}
|
|
||||||
Log.v("PlatLogoActivity", "color palette: " + str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Canvas canvas) {
|
protected void onPause() {
|
||||||
if (dp == 0) dp = getResources().getDisplayMetrics().density;
|
if (mBackslash != null) {
|
||||||
final float width = canvas.getWidth();
|
mBackslash.stopAnimating();
|
||||||
final float height = canvas.getHeight();
|
|
||||||
if (radius == 0) {
|
|
||||||
setPosition(width / 2, height / 2);
|
|
||||||
setRadius(width / 6);
|
|
||||||
}
|
|
||||||
final float inner_w = radius * 0.667f;
|
|
||||||
|
|
||||||
final Paint paint = new Paint();
|
|
||||||
paint.setStrokeCap(Paint.Cap.BUTT);
|
|
||||||
canvas.translate(x, y);
|
|
||||||
|
|
||||||
Path p = new Path();
|
|
||||||
p.moveTo(-radius, height);
|
|
||||||
p.lineTo(-radius, 0);
|
|
||||||
p.arcTo(-radius, -radius, radius, radius, -180, 270, false);
|
|
||||||
p.lineTo(-radius, radius);
|
|
||||||
|
|
||||||
float w = Math.max(canvas.getWidth(), canvas.getHeight()) * 1.414f;
|
|
||||||
paint.setStyle(Paint.Style.FILL);
|
|
||||||
|
|
||||||
int i=0;
|
|
||||||
while (w > radius*2 + inner_w*2) {
|
|
||||||
paint.setColor(0xFF000000 | palette[i % palette.length]);
|
|
||||||
// for a slower but more complete version:
|
|
||||||
// paint.setStrokeWidth(w);
|
|
||||||
// canvas.drawPath(p, paint);
|
|
||||||
canvas.drawOval(-w/2, -w/2, w/2, w/2, paint);
|
|
||||||
w -= inner_w * (1.1f + Math.sin((i/20f + offset) * 3.14159f));
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// the innermost circle needs to be a constant color to avoid rapid flashing
|
|
||||||
paint.setColor(0xFF000000 | palette[(darkest+1) % palette.length]);
|
|
||||||
canvas.drawOval(-radius, -radius, radius, radius, paint);
|
|
||||||
|
|
||||||
p.reset();
|
|
||||||
p.moveTo(-radius, height);
|
|
||||||
p.lineTo(-radius, 0);
|
|
||||||
p.arcTo(-radius, -radius, radius, radius, -180, 270, false);
|
|
||||||
p.lineTo(-radius + inner_w, radius);
|
|
||||||
|
|
||||||
paint.setStyle(Paint.Style.STROKE);
|
|
||||||
paint.setStrokeWidth(inner_w*2);
|
|
||||||
paint.setColor(palette[darkest]);
|
|
||||||
canvas.drawPath(p, paint);
|
|
||||||
paint.setStrokeWidth(inner_w);
|
|
||||||
paint.setColor(0xFFFFFFFF);
|
|
||||||
canvas.drawPath(p, paint);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setAlpha(int alpha) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setColorFilter(ColorFilter colorFilter) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getOpacity() {
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
mClicks = 0;
|
||||||
|
super.onPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
final float dp = getResources().getDisplayMetrics().density;
|
||||||
|
|
||||||
layout = new FrameLayout(this);
|
getWindow().getDecorView().setSystemUiVisibility(
|
||||||
setContentView(layout);
|
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
|
||||||
|
getWindow().setNavigationBarColor(0);
|
||||||
|
getWindow().setStatusBarColor(0);
|
||||||
|
|
||||||
bg = new PBackground();
|
getActionBar().hide();
|
||||||
layout.setBackground(bg);
|
|
||||||
|
|
||||||
final ContentResolver cr = getContentResolver();
|
setContentView(R.layout.platlogo_layout);
|
||||||
|
|
||||||
layout.setOnTouchListener(new View.OnTouchListener() {
|
mBackslash = new BackslashDrawable((int) (50 * dp));
|
||||||
final String TOUCH_STATS = "touch.stats";
|
|
||||||
|
|
||||||
final PointerCoords pc0 = new PointerCoords();
|
mOneView = findViewById(R.id.one);
|
||||||
final PointerCoords pc1 = new PointerCoords();
|
mOneView.setImageDrawable(new OneDrawable());
|
||||||
|
mZeroView = findViewById(R.id.zero);
|
||||||
|
mZeroView.setImageDrawable(new ZeroDrawable());
|
||||||
|
|
||||||
double pressure_min, pressure_max;
|
final ViewGroup root = (ViewGroup) mOneView.getParent();
|
||||||
int maxPointers;
|
root.setClipChildren(false);
|
||||||
int tapCount;
|
root.setBackground(mBackslash);
|
||||||
|
root.getBackground().setAlpha(0x20);
|
||||||
|
|
||||||
|
View.OnTouchListener tl = new View.OnTouchListener() {
|
||||||
|
float mOffsetX, mOffsetY;
|
||||||
|
long mClickTime;
|
||||||
|
ObjectAnimator mRotAnim;
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouch(View v, MotionEvent event) {
|
public boolean onTouch(View v, MotionEvent event) {
|
||||||
final float pressure = event.getPressure();
|
measureTouchPressure(event);
|
||||||
switch (event.getActionMasked()) {
|
switch (event.getActionMasked()) {
|
||||||
case MotionEvent.ACTION_DOWN:
|
case MotionEvent.ACTION_DOWN:
|
||||||
pressure_min = pressure_max = pressure;
|
v.animate().scaleX(1.1f).scaleY(1.1f);
|
||||||
// fall through
|
v.getParent().bringChildToFront(v);
|
||||||
case MotionEvent.ACTION_MOVE:
|
mOffsetX = event.getRawX() - v.getX();
|
||||||
if (pressure < pressure_min) pressure_min = pressure;
|
mOffsetY = event.getRawY() - v.getY();
|
||||||
if (pressure > pressure_max) pressure_max = pressure;
|
long now = System.currentTimeMillis();
|
||||||
final int pc = event.getPointerCount();
|
if (now - mClickTime < 350) {
|
||||||
if (pc > maxPointers) maxPointers = pc;
|
mRotAnim = ObjectAnimator.ofFloat(v, View.ROTATION,
|
||||||
if (pc > 1) {
|
v.getRotation(), v.getRotation() + 3600);
|
||||||
event.getPointerCoords(0, pc0);
|
mRotAnim.setDuration(10000);
|
||||||
event.getPointerCoords(1, pc1);
|
mRotAnim.start();
|
||||||
bg.setRadius((float) Math.hypot(pc0.x - pc1.x, pc0.y - pc1.y) / 2f);
|
mClickTime = 0;
|
||||||
|
} else {
|
||||||
|
mClickTime = now;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MotionEvent.ACTION_CANCEL:
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
v.setX(event.getRawX() - mOffsetX);
|
||||||
|
v.setY(event.getRawY() - mOffsetY);
|
||||||
|
v.performHapticFeedback(HapticFeedbackConstants.TEXT_HANDLE_MOVE);
|
||||||
|
break;
|
||||||
case MotionEvent.ACTION_UP:
|
case MotionEvent.ACTION_UP:
|
||||||
try {
|
v.performClick();
|
||||||
final String touchDataJson = Settings.System.getString(cr, TOUCH_STATS);
|
// fall through
|
||||||
final JSONObject touchData = new JSONObject(
|
case MotionEvent.ACTION_CANCEL:
|
||||||
touchDataJson != null ? touchDataJson : "{}");
|
v.animate().scaleX(1f).scaleY(1f);
|
||||||
if (touchData.has("min")) {
|
if (mRotAnim != null) mRotAnim.cancel();
|
||||||
pressure_min = Math.min(pressure_min, touchData.getDouble("min"));
|
testOverlap();
|
||||||
}
|
|
||||||
if (touchData.has("max")) {
|
|
||||||
pressure_max = Math.max(pressure_max, touchData.getDouble("max"));
|
|
||||||
}
|
|
||||||
touchData.put("min", pressure_min);
|
|
||||||
touchData.put("max", pressure_max);
|
|
||||||
Settings.System.putString(cr, TOUCH_STATS, touchData.toString());
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("PlatLogoActivity", "Can't write touch settings", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maxPointers == 1) {
|
|
||||||
tapCount ++;
|
|
||||||
if (tapCount < 7) {
|
|
||||||
bg.randomizePalette();
|
|
||||||
} else {
|
|
||||||
launchNextStage();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tapCount = 0;
|
|
||||||
}
|
|
||||||
maxPointers = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
|
findViewById(R.id.one).setOnTouchListener(tl);
|
||||||
|
findViewById(R.id.zero).setOnTouchListener(tl);
|
||||||
|
findViewById(R.id.text).setOnTouchListener(tl);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testOverlap() {
|
||||||
|
final float width = mZeroView.getWidth();
|
||||||
|
final float targetX = mZeroView.getX() + width * .2f;
|
||||||
|
final float targetY = mZeroView.getY() + width * .3f;
|
||||||
|
if (Math.hypot(targetX - mOneView.getX(), targetY - mOneView.getY()) < width * .2f
|
||||||
|
&& Math.abs(mOneView.getRotation() % 360 - 315) < 15) {
|
||||||
|
mOneView.animate().x(mZeroView.getX() + width * .2f);
|
||||||
|
mOneView.animate().y(mZeroView.getY() + width * .3f);
|
||||||
|
mOneView.setRotation(mOneView.getRotation() % 360);
|
||||||
|
mOneView.animate().rotation(315);
|
||||||
|
mOneView.performHapticFeedback(HapticFeedbackConstants.CONFIRM);
|
||||||
|
|
||||||
|
mBackslash.startAnimating();
|
||||||
|
|
||||||
|
mClicks++;
|
||||||
|
if (mClicks >= 7) {
|
||||||
|
launchNextStage();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mBackslash.stopAnimating();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void launchNextStage() {
|
private void launchNextStage() {
|
||||||
final ContentResolver cr = getContentResolver();
|
final ContentResolver cr = getContentResolver();
|
||||||
|
|
||||||
if (Settings.System.getLong(cr, Settings.System.EGG_MODE, 0) == 0) {
|
if (Settings.System.getLong(cr, "egg_mode" /* Settings.System.EGG_MODE */, 0) == 0) {
|
||||||
// For posterity: the moment this user unlocked the easter egg
|
// For posterity: the moment this user unlocked the easter egg
|
||||||
try {
|
try {
|
||||||
Settings.System.putLong(cr,
|
Settings.System.putLong(cr,
|
||||||
Settings.System.EGG_MODE,
|
"egg_mode", // Settings.System.EGG_MODE,
|
||||||
System.currentTimeMillis());
|
System.currentTimeMillis());
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
Log.e("PlatLogoActivity", "Can't write settings", e);
|
Log.e("com.android.internal.app.PlatLogoActivity", "Can't write settings", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -270,36 +185,206 @@ public class PlatLogoActivity extends Activity {
|
|||||||
| Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
| Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
||||||
.addCategory("com.android.internal.category.PLATLOGO"));
|
.addCategory("com.android.internal.category.PLATLOGO"));
|
||||||
} catch (ActivityNotFoundException ex) {
|
} catch (ActivityNotFoundException ex) {
|
||||||
Log.e("PlatLogoActivity", "No more eggs.");
|
Log.e("com.android.internal.app.PlatLogoActivity", "No more eggs.");
|
||||||
}
|
}
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static final String TOUCH_STATS = "touch.stats";
|
||||||
|
double mPressureMin = 0, mPressureMax = -1;
|
||||||
|
|
||||||
|
private void measureTouchPressure(MotionEvent event) {
|
||||||
|
final float pressure = event.getPressure();
|
||||||
|
switch (event.getActionMasked()) {
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
if (mPressureMax < 0) {
|
||||||
|
mPressureMin = mPressureMax = pressure;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
if (pressure < mPressureMin) mPressureMin = pressure;
|
||||||
|
if (pressure > mPressureMax) mPressureMax = pressure;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void syncTouchPressure() {
|
||||||
|
try {
|
||||||
|
final String touchDataJson = Settings.System.getString(
|
||||||
|
getContentResolver(), TOUCH_STATS);
|
||||||
|
final JSONObject touchData = new JSONObject(
|
||||||
|
touchDataJson != null ? touchDataJson : "{}");
|
||||||
|
if (touchData.has("min")) {
|
||||||
|
mPressureMin = Math.min(mPressureMin, touchData.getDouble("min"));
|
||||||
|
}
|
||||||
|
if (touchData.has("max")) {
|
||||||
|
mPressureMax = Math.max(mPressureMax, touchData.getDouble("max"));
|
||||||
|
}
|
||||||
|
if (mPressureMax >= 0) {
|
||||||
|
touchData.put("min", mPressureMin);
|
||||||
|
touchData.put("max", mPressureMax);
|
||||||
|
Settings.System.putString(getContentResolver(), TOUCH_STATS, touchData.toString());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("com.android.internal.app.PlatLogoActivity", "Can't write touch settings", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
|
syncTouchPressure();
|
||||||
bg.randomizePalette();
|
|
||||||
|
|
||||||
anim = new TimeAnimator();
|
|
||||||
anim.setTimeListener(
|
|
||||||
new TimeAnimator.TimeListener() {
|
|
||||||
@Override
|
|
||||||
public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
|
|
||||||
bg.setOffset((float) totalTime / 60000f);
|
|
||||||
bg.invalidateSelf();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
anim.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStop() {
|
public void onStop() {
|
||||||
if (anim != null) {
|
syncTouchPressure();
|
||||||
anim.cancel();
|
|
||||||
anim = null;
|
|
||||||
}
|
|
||||||
super.onStop();
|
super.onStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class ZeroDrawable extends Drawable {
|
||||||
|
int mTintColor;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas) {
|
||||||
|
sPaint.setColor(mTintColor | 0xFF000000);
|
||||||
|
|
||||||
|
canvas.save();
|
||||||
|
canvas.scale(canvas.getWidth() / 24f, canvas.getHeight() / 24f);
|
||||||
|
|
||||||
|
canvas.drawCircle(12f, 12f, 10f, sPaint);
|
||||||
|
canvas.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAlpha(int alpha) { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setColorFilter(ColorFilter colorFilter) { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTintList(ColorStateList tint) {
|
||||||
|
mTintColor = tint.getDefaultColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOpacity() {
|
||||||
|
return PixelFormat.TRANSLUCENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class OneDrawable extends Drawable {
|
||||||
|
int mTintColor;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas) {
|
||||||
|
sPaint.setColor(mTintColor | 0xFF000000);
|
||||||
|
|
||||||
|
canvas.save();
|
||||||
|
canvas.scale(canvas.getWidth() / 24f, canvas.getHeight() / 24f);
|
||||||
|
|
||||||
|
final Path p = new Path();
|
||||||
|
p.moveTo(12f, 21.83f);
|
||||||
|
p.rLineTo(0f, -19.67f);
|
||||||
|
p.rLineTo(-5f, 0f);
|
||||||
|
canvas.drawPath(p, sPaint);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAlpha(int alpha) { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setColorFilter(ColorFilter colorFilter) { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTintList(ColorStateList tint) {
|
||||||
|
mTintColor = tint.getDefaultColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOpacity() {
|
||||||
|
return PixelFormat.TRANSLUCENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class BackslashDrawable extends Drawable implements TimeAnimator.TimeListener {
|
||||||
|
Bitmap mTile;
|
||||||
|
Paint mPaint = new Paint();
|
||||||
|
BitmapShader mShader;
|
||||||
|
TimeAnimator mAnimator = new TimeAnimator();
|
||||||
|
Matrix mMatrix = new Matrix();
|
||||||
|
|
||||||
|
public void draw(Canvas canvas) {
|
||||||
|
canvas.drawPaint(mPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
BackslashDrawable(int width) {
|
||||||
|
mTile = Bitmap.createBitmap(width, width, Bitmap.Config.ALPHA_8);
|
||||||
|
mAnimator.setTimeListener(this);
|
||||||
|
|
||||||
|
final Canvas tileCanvas = new Canvas(mTile);
|
||||||
|
final float w = tileCanvas.getWidth();
|
||||||
|
final float h = tileCanvas.getHeight();
|
||||||
|
|
||||||
|
final Path path = new Path();
|
||||||
|
path.moveTo(0, 0);
|
||||||
|
path.lineTo(w / 2, 0);
|
||||||
|
path.lineTo(w, h / 2);
|
||||||
|
path.lineTo(w, h);
|
||||||
|
path.close();
|
||||||
|
|
||||||
|
path.moveTo(0, h / 2);
|
||||||
|
path.lineTo(w / 2, h);
|
||||||
|
path.lineTo(0, h);
|
||||||
|
path.close();
|
||||||
|
|
||||||
|
final Paint slashPaint = new Paint();
|
||||||
|
slashPaint.setAntiAlias(true);
|
||||||
|
slashPaint.setStyle(Paint.Style.FILL);
|
||||||
|
slashPaint.setColor(0xFF000000);
|
||||||
|
tileCanvas.drawPath(path, slashPaint);
|
||||||
|
|
||||||
|
//mPaint.setColor(0xFF0000FF);
|
||||||
|
mShader = new BitmapShader(mTile, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
|
||||||
|
mPaint.setShader(mShader);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startAnimating() {
|
||||||
|
if (!mAnimator.isStarted()) {
|
||||||
|
mAnimator.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopAnimating() {
|
||||||
|
if (mAnimator.isStarted()) {
|
||||||
|
mAnimator.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAlpha(int alpha) {
|
||||||
|
mPaint.setAlpha(alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setColorFilter(ColorFilter colorFilter) {
|
||||||
|
mPaint.setColorFilter(colorFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOpacity() {
|
||||||
|
return PixelFormat.TRANSLUCENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
|
||||||
|
if (mShader != null) {
|
||||||
|
mMatrix.postTranslate(deltaTime / 4f, 0);
|
||||||
|
mShader.setLocalMatrix(mMatrix);
|
||||||
|
invalidateSelf();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4662,8 +4662,9 @@
|
|||||||
android:process=":ui">
|
android:process=":ui">
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name="com.android.internal.app.PlatLogoActivity"
|
<activity android:name="com.android.internal.app.PlatLogoActivity"
|
||||||
android:theme="@style/Theme.Wallpaper.NoTitleBar.Fullscreen"
|
android:theme="@style/Theme.DeviceDefault.DayNight"
|
||||||
android:configChanges="orientation|keyboardHidden"
|
android:configChanges="orientation|keyboardHidden"
|
||||||
|
android:icon="@drawable/platlogo"
|
||||||
android:process=":ui">
|
android:process=":ui">
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name="com.android.internal.app.DisableCarModeActivity"
|
<activity android:name="com.android.internal.app.DisableCarModeActivity"
|
||||||
|
|||||||
42
core/res/res/drawable-nodpi/android_logotype.xml
Normal file
42
core/res/res/drawable-nodpi/android_logotype.xml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (C) 2015 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="290dp"
|
||||||
|
android:height="64dp"
|
||||||
|
android:viewportWidth="290.0"
|
||||||
|
android:viewportHeight="64.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M21.81,28.91c-7.44,0,-12.45,5.85,-12.45,13.37c0,7.52,5.01,13.37,12.45,13.37s12.45,-5.85,12.45,-13.37 C34.26,34.76,29.24,28.91,21.81,28.91 M20.13,20.55c6.02,0,11.03,3.09,13.37,6.43v-5.6l9.19,0l0,41.78l-6.24,0 c-1.63,0,-2.95,-1.32,-2.95,-2.95v-2.65C31.17,60.91,26.15,64,20.14,64C8.69,64,0,54.23,0,42.28C0,30.33,8.69,20.55,20.13,20.55"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M53.13,21.39l9.19,0l0,5.68c2.5,-4.18,7.27,-6.52,12.7,-6.52c9.69,0,15.96,6.85,15.96,17.46l0,25.15l-6.24,0 c-1.63,0,-2.95,-1.32,-2.95,-2.95l0,-20.7c0,-6.6,-3.34,-10.61,-8.69,-10.61c-6.1,0,-10.78,4.76,-10.78,13.7l0,20.55l-6.25,0 c-1.63,0,-2.95,-1.32,-2.95,-2.95L53.13,21.39z"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M120.06,28.91c-7.43,0,-12.45,5.85,-12.45,13.37c0,7.52,5.01,13.37,12.45,13.37c7.43,0,12.45,-5.85,12.45,-13.37 C132.51,34.76,127.5,28.91,120.06,28.91 M118.39,20.55c6.02,0,11.03,3.09,13.37,6.43l0,-26.49l9.19,0l0,62.66h-6.24 c-1.63,0,-2.95,-1.32,-2.95,-2.95v-2.65c-2.34,3.34,-7.35,6.43,-13.37,6.43c-11.45,0,-20.14,-9.77,-20.14,-21.72 C98.25,30.33,106.94,20.55,118.39,20.55"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M151.39,21.39l9.19,0v7.44c1.59,-4.76,6.27,-7.86,11.03,-7.86c1.17,0,2.34,0.08,3.59,0.34v9.44c-1.59,-0.5,-2.92,-0.75,-4.59,-0.75 c-5.26,0,-10.03,4.43,-10.03,12.78l0,20.39l-6.24,0c-1.63,0,-2.95,-1.32,-2.95,-2.95L151.39,21.39z"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M199.98,55.48c7.35,0,12.53,-5.77,12.53,-13.2c0,-7.44,-5.18,-13.2,-12.53,-13.2c-7.44,0,-12.62,5.77,-12.62,13.2 C187.37,49.71,192.55,55.48,199.98,55.48 M199.98,64c-12.37,0,-21.89,-9.61,-21.89,-21.72c0,-12.12,9.52,-21.73,21.89,-21.73 c12.37,0,21.89,9.61,21.89,21.73C221.87,54.39,212.35,64,199.98,64"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M229.32,21.39l9.19,0l0,41.78l-6.24,0c-1.63,0,-2.95,-1.32,-2.95,-2.95L229.32,21.39z M233.92,12.28 c-3.34,0,-6.18,-2.76,-6.18,-6.18c0,-3.34,2.84,-6.1,6.18,-6.1c3.43,0,6.1,2.76,6.1,6.1C240.02,9.53,237.34,12.28,233.92,12.28"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M267.87,28.91c-7.43,0,-12.45,5.85,-12.45,13.37c0,7.52,5.01,13.37,12.45,13.37c7.44,0,12.45,-5.85,12.45,-13.37 C280.32,34.76,275.31,28.91,267.87,28.91 M266.2,20.55c6.02,0,11.03,3.09,13.37,6.43l0,-26.49l9.19,0l0,62.66l-6.24,0 c-1.63,0,-2.95,-1.32,-2.95,-2.95v-2.65c-2.34,3.34,-7.35,6.43,-13.37,6.43c-11.44,0,-20.14,-9.77,-20.14,-21.72S254.76,20.55,266.2,20.55"/>
|
||||||
|
</vector>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
Copyright (C) 2018 The Android Open Source Project
|
Copyright (C) 2015 The Android Open Source Project
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -13,21 +13,15 @@ Copyright (C) 2018 The Android Open Source Project
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<vector
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
android:width="24dp"
|
||||||
android:name="vector"
|
android:height="24dp"
|
||||||
android:width="640dp"
|
android:viewportWidth="24.0"
|
||||||
android:height="640dp"
|
android:viewportHeight="24.0">
|
||||||
android:viewportWidth="64"
|
|
||||||
android:viewportHeight="64">
|
|
||||||
<path
|
<path
|
||||||
android:name="bg"
|
android:fillColor="#FF000000"
|
||||||
android:pathData="M 27 43 L 32 43 C 38.075 43 43 38.075 43 32 C 43 25.925 38.075 21 32 21 C 25.925 21 21 25.925 21 32 L 21 64"
|
android:pathData="M19.45,22.89l-10.250001,-10.249999l-2.6599998,2.6599998l-1.77,-1.7600002l4.43,-4.4300003l12.0199995,12.0199995l-1.7699986,1.7600002z"/>
|
||||||
android:strokeColor="#6823a1"
|
|
||||||
android:strokeWidth="16"/>
|
|
||||||
<path
|
<path
|
||||||
android:name="fg"
|
android:fillColor="#FF000000"
|
||||||
android:pathData="M 29 43 L 32 43 C 38.075 43 43 38.075 43 32 C 43 25.925 38.075 21 32 21 C 25.925 21 21 25.925 21 32 L 21 64"
|
android:pathData="M12,6a6,6 0,1 1,-6 6,6 6,0 0,1 6,-6m0,-2.5A8.5,8.5 0,1 0,20.5 12,8.51 8.51,0 0,0 12,3.5Z"/>
|
||||||
android:strokeColor="#ff0000"
|
|
||||||
android:strokeWidth="8"/>
|
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
50
core/res/res/layout/platlogo_layout.xml
Normal file
50
core/res/res/layout/platlogo_layout.xml
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2019 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:clipChildren="false"
|
||||||
|
android:background="@android:color/transparent">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/text"
|
||||||
|
android:layout_width="400dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:translationY="-100dp"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:layout_marginBottom="-80dp"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:src="@drawable/android_logotype"
|
||||||
|
android:tint="?android:attr/textColorPrimary"
|
||||||
|
/>
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/one"
|
||||||
|
android:layout_width="200dp"
|
||||||
|
android:layout_height="200dp"
|
||||||
|
android:layout_marginLeft="24dp"
|
||||||
|
android:layout_below="@id/text"
|
||||||
|
android:layout_alignLeft="@id/text"
|
||||||
|
android:tint="?android:attr/textColorPrimary"
|
||||||
|
/>
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/zero"
|
||||||
|
android:layout_width="200dp"
|
||||||
|
android:layout_height="200dp"
|
||||||
|
android:layout_marginRight="34dp"
|
||||||
|
android:layout_below="@id/text"
|
||||||
|
android:layout_alignRight="@id/text"
|
||||||
|
android:tint="?android:attr/textColorPrimary"
|
||||||
|
/>
|
||||||
|
</RelativeLayout>
|
||||||
@@ -3818,4 +3818,8 @@
|
|||||||
|
|
||||||
<java-symbol type="string" name="config_defaultSupervisionProfileOwnerComponent" />
|
<java-symbol type="string" name="config_defaultSupervisionProfileOwnerComponent" />
|
||||||
<java-symbol type="bool" name="config_inflateSignalStrength" />
|
<java-symbol type="bool" name="config_inflateSignalStrength" />
|
||||||
|
|
||||||
|
<java-symbol type="drawable" name="android_logotype" />
|
||||||
|
<java-symbol type="layout" name="platlogo_layout" />
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1,42 +1,40 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!--
|
|
||||||
Copyright (C) 2018 The Android Open Source Project
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.android.egg"
|
package="com.android.egg"
|
||||||
android:versionCode="1"
|
android:versionCode="1"
|
||||||
android:versionName="1.0">
|
android:versionName="1.0">
|
||||||
|
|
||||||
<uses-sdk android:minSdkVersion="28" />
|
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:icon="@drawable/icon"
|
android:icon="@drawable/q_icon"
|
||||||
android:label="@string/app_name">
|
android:label="@string/app_name">
|
||||||
|
<activity android:name=".quares.QuaresActivity"
|
||||||
<activity
|
android:icon="@drawable/q_icon"
|
||||||
android:name=".paint.PaintActivity"
|
android:label="@string/q_egg_name"
|
||||||
android:configChanges="orientation|keyboardHidden|screenSize|uiMode"
|
android:theme="@style/QuaresTheme">
|
||||||
android:label="@string/app_name"
|
|
||||||
android:theme="@style/AppTheme">
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<!-- <category android:name="android.intent.category.LAUNCHER" /> -->
|
<!-- <category android:name="android.intent.category.LAUNCHER" /> -->
|
||||||
<category android:name="com.android.internal.category.PLATLOGO" />
|
<category android:name="com.android.internal.category.PLATLOGO" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".paint.PaintActivity"
|
||||||
|
android:configChanges="orientation|keyboardHidden|screenSize|uiMode"
|
||||||
|
android:icon="@drawable/p_icon"
|
||||||
|
android:label="@string/p_egg_name"
|
||||||
|
android:theme="@style/AppTheme">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<!-- <category android:name="android.intent.category.DEFAULT" /> -->
|
||||||
|
<!-- <category android:name="android.intent.category.LAUNCHER" /> -->
|
||||||
|
<!-- <category android:name="com.android.internal.category.PLATLOGO" /> -->
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -15,4 +15,4 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<color xmlns:android="http://schemas.android.com/apk/res/android"
|
<color xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:color="#C5E1A5" />
|
android:color="@color/q_clue_text" />
|
||||||
|
|||||||
27
packages/EasterEgg/res/drawable/pixel_bg.xml
Normal file
27
packages/EasterEgg/res/drawable/pixel_bg.xml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright 2019 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:exitFadeDuration="100">
|
||||||
|
<item android:state_pressed="true">
|
||||||
|
<shape><solid android:color="@color/red"/></shape>
|
||||||
|
</item>
|
||||||
|
<item android:state_checked="true">
|
||||||
|
<shape><solid android:color="@color/pixel_on"/></shape>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<shape><solid android:color="@color/pixel_off"/></shape>
|
||||||
|
</item>
|
||||||
|
</selector>
|
||||||
27
packages/EasterEgg/res/drawable/q.xml
Normal file
27
packages/EasterEgg/res/drawable/q.xml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (C) 2015 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/q_icon_fg"
|
||||||
|
android:pathData="M19.45,22.89l-10.250001,-10.249999l-2.6599998,2.6599998l-1.77,-1.7600002l4.43,-4.4300003l12.0199995,12.0199995l-1.7699986,1.7600002z"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/q_icon_fg"
|
||||||
|
android:pathData="M12,6a6,6 0,1 1,-6 6,6 6,0 0,1 6,-6m0,-2.5A8.5,8.5 0,1 0,20.5 12,8.51 8.51,0 0,0 12,3.5Z"/>
|
||||||
|
</vector>
|
||||||
19
packages/EasterEgg/res/drawable/q_icon.xml
Normal file
19
packages/EasterEgg/res/drawable/q_icon.xml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (C) 2019 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@drawable/icon_bg"/>
|
||||||
|
<foreground android:drawable="@drawable/q_smaller"/>
|
||||||
|
</adaptive-icon>
|
||||||
23
packages/EasterEgg/res/drawable/q_smaller.xml
Normal file
23
packages/EasterEgg/res/drawable/q_smaller.xml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (C) 2019 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<inset xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:insetBottom="5dp"
|
||||||
|
android:insetLeft="5dp"
|
||||||
|
android:insetRight="5dp"
|
||||||
|
android:insetTop="5dp"
|
||||||
|
android:drawable="@drawable/q" />
|
||||||
46
packages/EasterEgg/res/layout/activity_quares.xml
Normal file
46
packages/EasterEgg/res/layout/activity_quares.xml
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright 2019 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:animateLayoutChanges="true"
|
||||||
|
tools:context="com.android.egg.quares.QuaresActivity">
|
||||||
|
|
||||||
|
<GridLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:alignmentMode="alignBounds"
|
||||||
|
android:id="@+id/grid"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/label"
|
||||||
|
android:layout_gravity="center_horizontal|bottom"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textSize="18dp"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:drawablePadding="8dp"
|
||||||
|
android:padding="12dp"
|
||||||
|
android:backgroundTint="@color/q_clue_bg_correct"
|
||||||
|
android:textColor="@color/q_clue_text"
|
||||||
|
android:layout_marginBottom="48dp"
|
||||||
|
android:elevation="30dp"
|
||||||
|
/>
|
||||||
|
</FrameLayout>
|
||||||
22
packages/EasterEgg/res/values-night/q_colors.xml
Normal file
22
packages/EasterEgg/res/values-night/q_colors.xml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright 2019 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<resources>
|
||||||
|
<color name="pixel_off">#000000</color>
|
||||||
|
<color name="pixel_on">#FFFFFF</color>
|
||||||
|
|
||||||
|
<color name="q_clue_bg">@color/navy</color>
|
||||||
|
<color name="q_clue_text">@color/tan</color>
|
||||||
|
</resources>
|
||||||
31
packages/EasterEgg/res/values/q_colors.xml
Normal file
31
packages/EasterEgg/res/values/q_colors.xml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright 2019 The Android Open Source Project
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<resources>
|
||||||
|
<color name="emerald">#3ddc84</color>
|
||||||
|
<color name="red">#f8c734</color>
|
||||||
|
<color name="navy">#073042</color>
|
||||||
|
<color name="vapor">#d7effe</color>
|
||||||
|
<color name="tan">#eff7cf</color>
|
||||||
|
|
||||||
|
<color name="pixel_off">#FFFFFF</color>
|
||||||
|
<color name="pixel_on">#000000</color>
|
||||||
|
|
||||||
|
<color name="q_clue_bg">@color/tan</color>
|
||||||
|
<color name="q_clue_text">@color/navy</color>
|
||||||
|
<color name="q_clue_bg_correct">@color/emerald</color>
|
||||||
|
|
||||||
|
<color name="q_icon_fg">@color/emerald</color>
|
||||||
|
</resources>
|
||||||
214
packages/EasterEgg/res/values/q_puzzles.xml
Normal file
214
packages/EasterEgg/res/values/q_puzzles.xml
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string-array name="puzzles">
|
||||||
|
|
||||||
|
<item>q</item>
|
||||||
|
<item>q</item>
|
||||||
|
<item>q</item>
|
||||||
|
<item>q</item>
|
||||||
|
<item>q</item>
|
||||||
|
|
||||||
|
<item>android:drawable/ic_info</item>
|
||||||
|
|
||||||
|
<item>android:drawable/stat_sys_adb</item>
|
||||||
|
<item>android:drawable/stat_sys_battery</item>
|
||||||
|
<item>android:drawable/stat_sys_phone_call</item>
|
||||||
|
<item>android:drawable/stat_sys_certificate_info</item>
|
||||||
|
<item>android:drawable/stat_sys_data_bluetooth</item>
|
||||||
|
<item>android:drawable/stat_sys_data_usb</item>
|
||||||
|
<item>android:drawable/stat_sys_download</item>
|
||||||
|
<item>android:drawable/stat_sys_gps_on</item>
|
||||||
|
<item>android:drawable/stat_sys_phone_call</item>
|
||||||
|
<item>android:drawable/stat_sys_tether_wifi</item>
|
||||||
|
<item>android:drawable/stat_sys_throttled</item>
|
||||||
|
<item>android:drawable/stat_sys_upload</item>
|
||||||
|
|
||||||
|
<item>android:drawable/stat_notify_car_mode</item>
|
||||||
|
<item>android:drawable/stat_notify_chat</item>
|
||||||
|
<item>android:drawable/stat_notify_disk_full</item>
|
||||||
|
<item>android:drawable/stat_notify_email_generic</item>
|
||||||
|
<item>android:drawable/stat_notify_error</item>
|
||||||
|
<item>android:drawable/stat_notify_gmail</item>
|
||||||
|
<item>android:drawable/stat_notify_missed_call</item>
|
||||||
|
<item>android:drawable/stat_notify_mmcc_indication_icn</item>
|
||||||
|
<item>android:drawable/stat_notify_more</item>
|
||||||
|
<item>android:drawable/stat_notify_rssi_in_range</item>
|
||||||
|
<item>android:drawable/stat_notify_sdcard</item>
|
||||||
|
<item>android:drawable/stat_notify_sdcard_prepare</item>
|
||||||
|
<item>android:drawable/stat_notify_sdcard_usb</item>
|
||||||
|
<item>android:drawable/stat_notify_sim_toolkit</item>
|
||||||
|
<item>android:drawable/stat_notify_sync</item>
|
||||||
|
<item>android:drawable/stat_notify_sync_anim0</item>
|
||||||
|
<item>android:drawable/stat_notify_sync_error</item>
|
||||||
|
<item>android:drawable/stat_notify_voicemail</item>
|
||||||
|
|
||||||
|
<item>android:drawable/ic_audio_alarm</item>
|
||||||
|
<item>android:drawable/ic_audio_alarm_mute</item>
|
||||||
|
<item>android:drawable/ic_bluetooth_share_icon</item>
|
||||||
|
<item>android:drawable/ic_bt_headphones_a2dp</item>
|
||||||
|
<item>android:drawable/ic_bt_headset_hfp</item>
|
||||||
|
<item>android:drawable/ic_bt_hearing_aid</item>
|
||||||
|
<item>android:drawable/ic_bt_laptop</item>
|
||||||
|
<item>android:drawable/ic_bt_misc_hid</item>
|
||||||
|
<item>android:drawable/ic_bt_network_pan</item>
|
||||||
|
<item>android:drawable/ic_bt_pointing_hid</item>
|
||||||
|
<item>android:drawable/ic_corp_badge</item>
|
||||||
|
<item>android:drawable/ic_expand_more</item>
|
||||||
|
<item>android:drawable/ic_faster_emergency</item>
|
||||||
|
<item>android:drawable/ic_file_copy</item>
|
||||||
|
<item>android:drawable/ic_info_outline_24</item>
|
||||||
|
<item>android:drawable/ic_lock</item>
|
||||||
|
<item>android:drawable/ic_lock_bugreport</item>
|
||||||
|
<item>android:drawable/ic_lock_open</item>
|
||||||
|
<item>android:drawable/ic_lock_power_off</item>
|
||||||
|
<item>android:drawable/ic_lockscreen_ime</item>
|
||||||
|
<item>android:drawable/ic_mode_edit</item>
|
||||||
|
<item>android:drawable/ic_phone</item>
|
||||||
|
<item>android:drawable/ic_qs_airplane</item>
|
||||||
|
<item>android:drawable/ic_qs_auto_rotate</item>
|
||||||
|
<item>android:drawable/ic_qs_battery_saver</item>
|
||||||
|
<item>android:drawable/ic_qs_bluetooth</item>
|
||||||
|
<item>android:drawable/ic_qs_dnd</item>
|
||||||
|
<item>android:drawable/ic_qs_flashlight</item>
|
||||||
|
<item>android:drawable/ic_qs_night_display_on</item>
|
||||||
|
<item>android:drawable/ic_restart</item>
|
||||||
|
<item>android:drawable/ic_screenshot</item>
|
||||||
|
<item>android:drawable/ic_settings_bluetooth</item>
|
||||||
|
<item>android:drawable/ic_signal_cellular_0_4_bar</item>
|
||||||
|
<item>android:drawable/ic_signal_cellular_0_5_bar</item>
|
||||||
|
<item>android:drawable/ic_signal_cellular_1_4_bar</item>
|
||||||
|
<item>android:drawable/ic_signal_cellular_1_5_bar</item>
|
||||||
|
<item>android:drawable/ic_signal_cellular_2_4_bar</item>
|
||||||
|
<item>android:drawable/ic_signal_cellular_2_5_bar</item>
|
||||||
|
<item>android:drawable/ic_signal_cellular_3_4_bar</item>
|
||||||
|
<item>android:drawable/ic_signal_cellular_3_5_bar</item>
|
||||||
|
<item>android:drawable/ic_signal_cellular_4_4_bar</item>
|
||||||
|
<item>android:drawable/ic_signal_cellular_4_5_bar</item>
|
||||||
|
<item>android:drawable/ic_signal_cellular_5_5_bar</item>
|
||||||
|
<item>android:drawable/ic_signal_location</item>
|
||||||
|
<item>android:drawable/ic_wifi_signal_0</item>
|
||||||
|
<item>android:drawable/ic_wifi_signal_1</item>
|
||||||
|
<item>android:drawable/ic_wifi_signal_2</item>
|
||||||
|
<item>android:drawable/ic_wifi_signal_3</item>
|
||||||
|
<item>android:drawable/ic_wifi_signal_4</item>
|
||||||
|
<item>android:drawable/perm_group_activity_recognition</item>
|
||||||
|
<item>android:drawable/perm_group_calendar</item>
|
||||||
|
<item>android:drawable/perm_group_call_log</item>
|
||||||
|
<item>android:drawable/perm_group_camera</item>
|
||||||
|
<item>android:drawable/perm_group_contacts</item>
|
||||||
|
<item>android:drawable/perm_group_location</item>
|
||||||
|
<item>android:drawable/perm_group_microphone</item>
|
||||||
|
<item>android:drawable/perm_group_phone_calls</item>
|
||||||
|
<item>android:drawable/perm_group_sensors</item>
|
||||||
|
<item>android:drawable/perm_group_sms</item>
|
||||||
|
<item>android:drawable/perm_group_storage</item>
|
||||||
|
<item>android:drawable/perm_group_visual</item>
|
||||||
|
|
||||||
|
<item>com.android.settings:drawable/ic_add_24dp</item>
|
||||||
|
<item>com.android.settings:drawable/ic_airplanemode_active</item>
|
||||||
|
<item>com.android.settings:drawable/ic_android</item>
|
||||||
|
<item>com.android.settings:drawable/ic_apps</item>
|
||||||
|
<item>com.android.settings:drawable/ic_arrow_back</item>
|
||||||
|
<item>com.android.settings:drawable/ic_arrow_down_24dp</item>
|
||||||
|
<item>com.android.settings:drawable/ic_battery_charging_full</item>
|
||||||
|
<item>com.android.settings:drawable/ic_battery_status_bad_24dp</item>
|
||||||
|
<item>com.android.settings:drawable/ic_battery_status_good_24dp</item>
|
||||||
|
<item>com.android.settings:drawable/ic_battery_status_maybe_24dp</item>
|
||||||
|
<item>com.android.settings:drawable/ic_call_24dp</item>
|
||||||
|
<item>com.android.settings:drawable/ic_cancel</item>
|
||||||
|
<item>com.android.settings:drawable/ic_cast_24dp</item>
|
||||||
|
<item>com.android.settings:drawable/ic_chevron_right_24dp</item>
|
||||||
|
<item>com.android.settings:drawable/ic_data_saver</item>
|
||||||
|
<item>com.android.settings:drawable/ic_delete</item>
|
||||||
|
<item>com.android.settings:drawable/ic_devices_other</item>
|
||||||
|
<item>com.android.settings:drawable/ic_devices_other_opaque_black</item>
|
||||||
|
<item>com.android.settings:drawable/ic_do_not_disturb_on_24dp</item>
|
||||||
|
<item>com.android.settings:drawable/ic_eject_24dp</item>
|
||||||
|
<item>com.android.settings:drawable/ic_expand_less</item>
|
||||||
|
<item>com.android.settings:drawable/ic_expand_more_inverse</item>
|
||||||
|
<item>com.android.settings:drawable/ic_folder_vd_theme_24</item>
|
||||||
|
<item>com.android.settings:drawable/ic_friction_lock_closed</item>
|
||||||
|
<item>com.android.settings:drawable/ic_gray_scale_24dp</item>
|
||||||
|
<item>com.android.settings:drawable/ic_headset_24dp</item>
|
||||||
|
<item>com.android.settings:drawable/ic_help</item>
|
||||||
|
<item>com.android.settings:drawable/ic_local_movies</item>
|
||||||
|
<item>com.android.settings:drawable/ic_lock</item>
|
||||||
|
<item>com.android.settings:drawable/ic_media_stream</item>
|
||||||
|
<item>com.android.settings:drawable/ic_network_cell</item>
|
||||||
|
<item>com.android.settings:drawable/ic_notifications</item>
|
||||||
|
<item>com.android.settings:drawable/ic_notifications_off_24dp</item>
|
||||||
|
<item>com.android.settings:drawable/ic_phone_info</item>
|
||||||
|
<item>com.android.settings:drawable/ic_photo_library</item>
|
||||||
|
<item>com.android.settings:drawable/ic_settings_accessibility</item>
|
||||||
|
<item>com.android.settings:drawable/ic_settings_accounts</item>
|
||||||
|
<item>com.android.settings:drawable/ic_settings_backup</item>
|
||||||
|
<item>com.android.settings:drawable/ic_settings_battery_white</item>
|
||||||
|
<item>com.android.settings:drawable/ic_settings_data_usage</item>
|
||||||
|
<item>com.android.settings:drawable/ic_settings_date_time</item>
|
||||||
|
<item>com.android.settings:drawable/ic_settings_delete</item>
|
||||||
|
<item>com.android.settings:drawable/ic_settings_display_white</item>
|
||||||
|
<item>com.android.settings:drawable/ic_settings_home</item>
|
||||||
|
<item>com.android.settings:drawable/ic_settings_location</item>
|
||||||
|
<item>com.android.settings:drawable/ic_settings_night_display</item>
|
||||||
|
<item>com.android.settings:drawable/ic_settings_open</item>
|
||||||
|
<item>com.android.settings:drawable/ic_settings_print</item>
|
||||||
|
<item>com.android.settings:drawable/ic_settings_privacy</item>
|
||||||
|
<item>com.android.settings:drawable/ic_settings_security_white</item>
|
||||||
|
<item>com.android.settings:drawable/ic_settings_sim</item>
|
||||||
|
<item>com.android.settings:drawable/ic_settings_wireless</item>
|
||||||
|
<item>com.android.settings:drawable/ic_storage</item>
|
||||||
|
<item>com.android.settings:drawable/ic_storage_white</item>
|
||||||
|
<item>com.android.settings:drawable/ic_suggestion_night_display</item>
|
||||||
|
<item>com.android.settings:drawable/ic_sync</item>
|
||||||
|
<item>com.android.settings:drawable/ic_system_update</item>
|
||||||
|
<item>com.android.settings:drawable/ic_videogame_vd_theme_24</item>
|
||||||
|
<item>com.android.settings:drawable/ic_volume_ringer_vibrate</item>
|
||||||
|
<item>com.android.settings:drawable/ic_volume_up_24dp</item>
|
||||||
|
<item>com.android.settings:drawable/ic_vpn_key</item>
|
||||||
|
<item>com.android.settings:drawable/ic_wifi_tethering</item>
|
||||||
|
|
||||||
|
<item>com.android.systemui:drawable/ic_alarm</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_alarm_dim</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_arrow_back</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_bluetooth_connected</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_brightness_thumb</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_camera</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_cast</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_cast_connected</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_cast_connected_fill</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_close_white</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_data_saver</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_data_saver_off</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_drag_handle</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_headset</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_headset_mic</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_hotspot</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_invert_colors</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_location</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_lockscreen_ime</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_notifications_alert</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_notifications_silence</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_power_low</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_power_saver</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_qs_bluetooth_connecting</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_qs_bluetooth_on</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_qs_cancel</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_qs_no_sim</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_screenshot_delete</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_settings</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_swap_vert</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_volume_alarm</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_volume_alarm_mute</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_volume_media</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_volume_media_mute</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_volume_ringer</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_volume_ringer_mute</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_volume_ringer_vibrate</item>
|
||||||
|
<item>com.android.systemui:drawable/ic_volume_voice</item>
|
||||||
|
<item>com.android.systemui:drawable/stat_sys_camera</item>
|
||||||
|
<item>com.android.systemui:drawable/stat_sys_managed_profile_status</item>
|
||||||
|
<item>com.android.systemui:drawable/stat_sys_mic_none</item>
|
||||||
|
<item>com.android.systemui:drawable/stat_sys_vpn_ic</item>
|
||||||
|
|
||||||
|
</string-array>
|
||||||
|
</resources>
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
<!--
|
|
||||||
Copyright (C) 2018 The Android Open Source Project
|
Copyright (C) 2018 The Android Open Source Project
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@@ -15,5 +14,11 @@ Copyright (C) 2018 The Android Open Source Project
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<string name="app_name" translatable="false">PAINT.APK</string>
|
<string name="app_name" translatable="false">Android Q Easter Egg</string>
|
||||||
|
|
||||||
|
<!-- name of the Q easter egg, a nonogram-style icon puzzle -->
|
||||||
|
<string name="q_egg_name" translatable="false">Icon Quiz</string>
|
||||||
|
|
||||||
|
<!-- name of the P easter egg, a humble paint program -->
|
||||||
|
<string name="p_egg_name" translatable="false">PAINT.APK</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -20,4 +20,16 @@
|
|||||||
<item name="android:windowLightNavigationBar">true</item>
|
<item name="android:windowLightNavigationBar">true</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="QuaresTheme" parent="@android:style/Theme.DeviceDefault.DayNight">
|
||||||
|
<item name="android:windowIsTranslucent">true</item>
|
||||||
|
<item name="android:windowBackground">@android:color/transparent</item>
|
||||||
|
<item name="android:colorBackgroundCacheHint">@null</item>
|
||||||
|
<item name="android:windowShowWallpaper">true</item>
|
||||||
|
<item name="android:windowContentOverlay">@null</item>
|
||||||
|
<item name="android:windowNoTitle">true</item>
|
||||||
|
<item name="android:windowFullscreen">true</item>
|
||||||
|
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||||
|
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
168
packages/EasterEgg/src/com/android/egg/quares/Quare.kt
Normal file
168
packages/EasterEgg/src/com/android/egg/quares/Quare.kt
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.egg.quares
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.Canvas
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.graphics.drawable.Icon
|
||||||
|
import android.os.Parcel
|
||||||
|
import android.os.Parcelable
|
||||||
|
import java.util.ArrayList
|
||||||
|
import kotlin.math.abs
|
||||||
|
import kotlin.math.round
|
||||||
|
|
||||||
|
class Quare(val width: Int, val height: Int, val depth: Int) : Parcelable {
|
||||||
|
private val data: IntArray = IntArray(width * height)
|
||||||
|
private val user: IntArray = data.copyOf()
|
||||||
|
|
||||||
|
private fun loadAndQuantize(bitmap8bpp: Bitmap) {
|
||||||
|
bitmap8bpp.getPixels(data, 0, width, 0, 0, width, height)
|
||||||
|
if (depth == 8) return
|
||||||
|
val s = (255f / depth)
|
||||||
|
for (i in 0 until data.size) {
|
||||||
|
var f = (data[i] ushr 24).toFloat() / s
|
||||||
|
// f = f.pow(0.75f) // gamma adjust for bolder lines
|
||||||
|
f *= 1.25f // brightness adjust for bolder lines
|
||||||
|
f.coerceAtMost(1f)
|
||||||
|
data[i] = (round(f) * s).toInt() shl 24
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isBlank(): Boolean {
|
||||||
|
return data.sum() == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fun load(drawable: Drawable) {
|
||||||
|
val resized = Bitmap.createBitmap(width, height, Bitmap.Config.ALPHA_8)
|
||||||
|
val canvas = Canvas(resized)
|
||||||
|
drawable.setBounds(0, 0, width, height)
|
||||||
|
drawable.setTint(0xFF000000.toInt())
|
||||||
|
drawable.draw(canvas)
|
||||||
|
loadAndQuantize(resized)
|
||||||
|
resized.recycle()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun load(context: Context, icon: Icon) {
|
||||||
|
icon.loadDrawable(context)?.let {
|
||||||
|
load(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bitmap(): Bitmap {
|
||||||
|
return Bitmap.createBitmap(data, width, height, Bitmap.Config.ALPHA_8)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getUserMark(x: Int, y: Int): Int {
|
||||||
|
return user[y * width + x] ushr 24
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setUserMark(x: Int, y: Int, v: Int) {
|
||||||
|
user[y * width + x] = v shl 24
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getDataAt(x: Int, y: Int): Int {
|
||||||
|
return data[y * width + x] ushr 24
|
||||||
|
}
|
||||||
|
|
||||||
|
fun check(): Boolean {
|
||||||
|
return data.contentEquals(user)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun check(xSel: Int, ySel: Int): Boolean {
|
||||||
|
val xStart = if (xSel < 0) 0 else xSel
|
||||||
|
val xEnd = if (xSel < 0) width - 1 else xSel
|
||||||
|
val yStart = if (ySel < 0) 0 else ySel
|
||||||
|
val yEnd = if (ySel < 0) height - 1 else ySel
|
||||||
|
for (y in yStart..yEnd)
|
||||||
|
for (x in xStart..xEnd)
|
||||||
|
if (getDataAt(x, y) != getUserMark(x, y)) return false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun errors(): IntArray {
|
||||||
|
return IntArray(width * height) {
|
||||||
|
abs(data[it] - user[it])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getRowClue(y: Int): IntArray {
|
||||||
|
return getClue(-1, y)
|
||||||
|
}
|
||||||
|
fun getColumnClue(x: Int): IntArray {
|
||||||
|
return getClue(x, -1)
|
||||||
|
}
|
||||||
|
fun getClue(xSel: Int, ySel: Int): IntArray {
|
||||||
|
val arr = ArrayList<Int>()
|
||||||
|
var len = 0
|
||||||
|
val xStart = if (xSel < 0) 0 else xSel
|
||||||
|
val xEnd = if (xSel < 0) width - 1 else xSel
|
||||||
|
val yStart = if (ySel < 0) 0 else ySel
|
||||||
|
val yEnd = if (ySel < 0) height - 1 else ySel
|
||||||
|
for (y in yStart..yEnd)
|
||||||
|
for (x in xStart..xEnd)
|
||||||
|
if (getDataAt(x, y) != 0) {
|
||||||
|
len++
|
||||||
|
} else if (len > 0) {
|
||||||
|
arr.add(len)
|
||||||
|
len = 0
|
||||||
|
}
|
||||||
|
if (len > 0) arr.add(len)
|
||||||
|
else if (arr.size == 0) arr.add(0)
|
||||||
|
return arr.toIntArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun resetUserMarks() {
|
||||||
|
user.forEachIndexed { index, _ -> user[index] = 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parcelable interface
|
||||||
|
|
||||||
|
override fun describeContents(): Int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun writeToParcel(p: Parcel?, flags: Int) {
|
||||||
|
p?.let {
|
||||||
|
p.writeInt(width)
|
||||||
|
p.writeInt(height)
|
||||||
|
p.writeInt(depth)
|
||||||
|
p.writeIntArray(data)
|
||||||
|
p.writeIntArray(user)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object CREATOR : Parcelable.Creator<Quare> {
|
||||||
|
override fun createFromParcel(p: Parcel?): Quare {
|
||||||
|
return p!!.let {
|
||||||
|
Quare(
|
||||||
|
p.readInt(), // width
|
||||||
|
p.readInt(), // height
|
||||||
|
p.readInt() // depth
|
||||||
|
).also {
|
||||||
|
p.readIntArray(it.data)
|
||||||
|
p.readIntArray(it.user)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun newArray(size: Int): Array<Quare?> {
|
||||||
|
return arrayOfNulls(size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
312
packages/EasterEgg/src/com/android/egg/quares/QuaresActivity.kt
Normal file
312
packages/EasterEgg/src/com/android/egg/quares/QuaresActivity.kt
Normal file
@@ -0,0 +1,312 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.egg.quares
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.res.Configuration
|
||||||
|
import android.graphics.Canvas
|
||||||
|
import android.graphics.Paint
|
||||||
|
import android.graphics.Typeface
|
||||||
|
import android.graphics.drawable.Icon
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.text.StaticLayout
|
||||||
|
import android.text.TextPaint
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.View
|
||||||
|
import android.view.View.GONE
|
||||||
|
import android.view.View.VISIBLE
|
||||||
|
import android.widget.Button
|
||||||
|
import android.widget.CompoundButton
|
||||||
|
import android.widget.GridLayout
|
||||||
|
|
||||||
|
import java.util.Random
|
||||||
|
|
||||||
|
import com.android.egg.R
|
||||||
|
|
||||||
|
const val TAG = "Quares"
|
||||||
|
|
||||||
|
class QuaresActivity : Activity() {
|
||||||
|
private var q: Quare = Quare(16, 16, 1)
|
||||||
|
private var resId = 0
|
||||||
|
private var resName = ""
|
||||||
|
private var icon: Icon? = null
|
||||||
|
|
||||||
|
private lateinit var label: Button
|
||||||
|
private lateinit var grid: GridLayout
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
window.decorView.systemUiVisibility =
|
||||||
|
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||||
|
|
||||||
|
actionBar?.hide()
|
||||||
|
|
||||||
|
setContentView(R.layout.activity_quares)
|
||||||
|
|
||||||
|
grid = findViewById(R.id.grid)
|
||||||
|
label = findViewById(R.id.label)
|
||||||
|
|
||||||
|
if (savedInstanceState != null) {
|
||||||
|
Log.v(TAG, "restoring puzzle from state")
|
||||||
|
q = savedInstanceState.getParcelable("q") ?: q
|
||||||
|
resId = savedInstanceState.getInt("resId")
|
||||||
|
resName = savedInstanceState.getString("resName", "")
|
||||||
|
loadPuzzle()
|
||||||
|
}
|
||||||
|
|
||||||
|
label.setOnClickListener { newPuzzle() }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
if (resId == 0) {
|
||||||
|
// lazy init from onCreate
|
||||||
|
newPuzzle()
|
||||||
|
}
|
||||||
|
checkVictory()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
|
super.onSaveInstanceState(outState)
|
||||||
|
|
||||||
|
outState.putParcelable("q", q)
|
||||||
|
outState.putInt("resId", resId)
|
||||||
|
outState.putString("resName", resName)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun newPuzzle() {
|
||||||
|
Log.v(TAG, "new puzzle...")
|
||||||
|
|
||||||
|
q.resetUserMarks()
|
||||||
|
val oldResId = resId
|
||||||
|
resId = android.R.drawable.stat_sys_warning
|
||||||
|
try {
|
||||||
|
for (tries in 0..3) {
|
||||||
|
val ar = resources.obtainTypedArray(R.array.puzzles)
|
||||||
|
val newName = ar.getString(Random().nextInt(ar.length()))
|
||||||
|
if (newName == null) continue
|
||||||
|
|
||||||
|
Log.v(TAG, "Looking for icon " + newName)
|
||||||
|
|
||||||
|
val pkg = getPackageNameForResourceName(newName)
|
||||||
|
val newId = packageManager.getResourcesForApplication(pkg)
|
||||||
|
.getIdentifier(newName, "drawable", pkg)
|
||||||
|
if (newId == 0) {
|
||||||
|
Log.v(TAG, "oops, " + newName + " doesn't resolve from pkg " + pkg)
|
||||||
|
} else if (newId != oldResId) {
|
||||||
|
// got a good one
|
||||||
|
resId = newId
|
||||||
|
resName = newName
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: RuntimeException) {
|
||||||
|
Log.v(TAG, "problem loading puzzle, using fallback", e)
|
||||||
|
}
|
||||||
|
loadPuzzle()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getPackageNameForResourceName(name: String): String {
|
||||||
|
return if (name.contains(":") && !name.startsWith("android:")) {
|
||||||
|
name.substring(0, name.indexOf(":"))
|
||||||
|
} else {
|
||||||
|
packageName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkVictory() {
|
||||||
|
if (q.check()) {
|
||||||
|
val dp = resources.displayMetrics.density
|
||||||
|
|
||||||
|
val label: Button = findViewById(R.id.label)
|
||||||
|
label.text = resName.replace(Regex("^.*/"), "")
|
||||||
|
val drawable = icon?.loadDrawable(this)?.also {
|
||||||
|
it.setBounds(0, 0, (32 * dp).toInt(), (32 * dp).toInt())
|
||||||
|
it.setTint(label.currentTextColor)
|
||||||
|
}
|
||||||
|
label.setCompoundDrawables(drawable, null, null, null)
|
||||||
|
|
||||||
|
label.visibility = VISIBLE
|
||||||
|
} else {
|
||||||
|
label.visibility = GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadPuzzle() {
|
||||||
|
Log.v(TAG, "loading " + resName + " at " + q.width + "x" + q.height)
|
||||||
|
|
||||||
|
val dp = resources.displayMetrics.density
|
||||||
|
|
||||||
|
icon = Icon.createWithResource(getPackageNameForResourceName(resName), resId)
|
||||||
|
q.load(this, icon!!)
|
||||||
|
|
||||||
|
if (q.isBlank()) {
|
||||||
|
// this is a really boring puzzle, let's try again
|
||||||
|
resId = 0
|
||||||
|
resName = ""
|
||||||
|
recreate()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
grid.removeAllViews()
|
||||||
|
grid.columnCount = q.width + 1
|
||||||
|
grid.rowCount = q.height + 1
|
||||||
|
|
||||||
|
label.visibility = GONE
|
||||||
|
|
||||||
|
val orientation = resources.configuration.orientation
|
||||||
|
|
||||||
|
// clean this up a bit
|
||||||
|
val minSide = resources.configuration.smallestScreenWidthDp - 25 // ish
|
||||||
|
val size = (minSide / (q.height + 0.5) * dp).toInt()
|
||||||
|
|
||||||
|
val sb = StringBuffer()
|
||||||
|
|
||||||
|
for (j in 0 until grid.rowCount) {
|
||||||
|
for (i in 0 until grid.columnCount) {
|
||||||
|
val tv: View
|
||||||
|
val params = GridLayout.LayoutParams().also {
|
||||||
|
it.width = size
|
||||||
|
it.height = size
|
||||||
|
it.setMargins(1, 1, 1, 1)
|
||||||
|
it.rowSpec = GridLayout.spec(GridLayout.UNDEFINED, GridLayout.TOP) // UGH
|
||||||
|
}
|
||||||
|
val x = i - 1
|
||||||
|
val y = j - 1
|
||||||
|
if (i > 0 && j > 0) {
|
||||||
|
if (i == 1 && j > 1) sb.append("\n")
|
||||||
|
sb.append(if (q.getDataAt(x, y) == 0) " " else "X")
|
||||||
|
tv = PixelButton(this)
|
||||||
|
tv.isChecked = q.getUserMark(x, y) != 0
|
||||||
|
tv.setOnClickListener {
|
||||||
|
q.setUserMark(x, y, if (tv.isChecked) 0xFF else 0)
|
||||||
|
val columnCorrect = (grid.getChildAt(i) as? ClueView)?.check(q) ?: false
|
||||||
|
val rowCorrect = (grid.getChildAt(j*(grid.columnCount)) as? ClueView)
|
||||||
|
?.check(q) ?: false
|
||||||
|
if (columnCorrect && rowCorrect) {
|
||||||
|
checkVictory()
|
||||||
|
} else {
|
||||||
|
label.visibility = GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (i == j) { // 0,0
|
||||||
|
tv = View(this)
|
||||||
|
tv.visibility = GONE
|
||||||
|
} else {
|
||||||
|
tv = ClueView(this)
|
||||||
|
if (j == 0) {
|
||||||
|
tv.textRotation = 90f
|
||||||
|
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||||
|
params.height /= 2
|
||||||
|
tv.showText = false
|
||||||
|
} else {
|
||||||
|
params.height = (96 * dp).toInt()
|
||||||
|
}
|
||||||
|
if (x >= 0) {
|
||||||
|
tv.setColumn(q, x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == 0) {
|
||||||
|
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||||
|
params.width /= 2
|
||||||
|
tv.showText = false
|
||||||
|
} else {
|
||||||
|
params.width = (96 * dp).toInt()
|
||||||
|
}
|
||||||
|
if (y >= 0) {
|
||||||
|
tv.setRow(q, y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
grid.addView(tv, params)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.v(TAG, "icon: \n" + sb)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PixelButton(context: Context) : CompoundButton(context) {
|
||||||
|
init {
|
||||||
|
setBackgroundResource(R.drawable.pixel_bg)
|
||||||
|
isClickable = true
|
||||||
|
isEnabled = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClueView(context: Context) : View(context) {
|
||||||
|
var row: Int = -1
|
||||||
|
var column: Int = -1
|
||||||
|
var textRotation: Float = 0f
|
||||||
|
var text: CharSequence = ""
|
||||||
|
var showText = true
|
||||||
|
val paint: TextPaint
|
||||||
|
val incorrectColor: Int
|
||||||
|
val correctColor: Int
|
||||||
|
|
||||||
|
init {
|
||||||
|
setBackgroundColor(0)
|
||||||
|
paint = TextPaint().also {
|
||||||
|
it.textSize = 14f * context.resources.displayMetrics.density
|
||||||
|
it.color = context.getColor(R.color.q_clue_text)
|
||||||
|
it.typeface = Typeface.DEFAULT_BOLD
|
||||||
|
it.textAlign = Paint.Align.CENTER
|
||||||
|
}
|
||||||
|
incorrectColor = context.getColor(R.color.q_clue_bg)
|
||||||
|
correctColor = context.getColor(R.color.q_clue_bg_correct)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setRow(q: Quare, row: Int): Boolean {
|
||||||
|
this.row = row
|
||||||
|
this.column = -1
|
||||||
|
this.textRotation = 0f
|
||||||
|
text = q.getRowClue(row).joinToString("-")
|
||||||
|
return check(q)
|
||||||
|
}
|
||||||
|
fun setColumn(q: Quare, column: Int): Boolean {
|
||||||
|
this.column = column
|
||||||
|
this.row = -1
|
||||||
|
this.textRotation = 90f
|
||||||
|
text = q.getColumnClue(column).joinToString("-")
|
||||||
|
return check(q)
|
||||||
|
}
|
||||||
|
fun check(q: Quare): Boolean {
|
||||||
|
val correct = q.check(column, row)
|
||||||
|
setBackgroundColor(if (correct) correctColor else incorrectColor)
|
||||||
|
return correct
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDraw(canvas: Canvas?) {
|
||||||
|
super.onDraw(canvas)
|
||||||
|
if (!showText) return
|
||||||
|
canvas?.let {
|
||||||
|
val x = canvas.width / 2f
|
||||||
|
val y = canvas.height / 2f
|
||||||
|
var textWidth = canvas.width
|
||||||
|
if (textRotation != 0f) {
|
||||||
|
canvas.rotate(textRotation, x, y)
|
||||||
|
textWidth = canvas.height
|
||||||
|
}
|
||||||
|
val textLayout = StaticLayout.Builder.obtain(
|
||||||
|
text, 0, text.length, paint, textWidth).build()
|
||||||
|
canvas.translate(x, y - textLayout.height / 2)
|
||||||
|
textLayout.draw(canvas)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user