Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d1f9f533 authored by Dan Sandler's avatar Dan Sandler
Browse files

P is for PAINT.

Bug: 109925861
Test: adb shell am start \
        -a android.intent.action.MAIN \
        -c com.android.internal.category.PLATLOGO
Change-Id: Ic3020007c716be264e9523d6dbae9e13a95fa571
parent 2eb94adb
Loading
Loading
Loading
Loading
+78 −2
Original line number Diff line number Diff line
@@ -18,6 +18,9 @@ package com.android.internal.app;

import android.animation.TimeAnimator;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.ContentResolver;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
@@ -25,12 +28,15 @@ import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.view.MotionEvent;
import android.view.MotionEvent.PointerCoords;
import android.view.View;
import android.widget.FrameLayout;

import org.json.JSONObject;

public class PlatLogoActivity extends Activity {
    FrameLayout layout;
    TimeAnimator anim;
@@ -87,7 +93,7 @@ public class PlatLogoActivity extends Activity {
            darkest = 0;
            for (int i=0; i<slots; i++) {
                palette[i] = Color.HSVToColor(color);
                color[0] += 360f/slots;
                color[0] = (color[0] + 360f/slots) % 360f;
                if (lum(palette[i]) < lum(palette[darkest])) darkest = i;
            }

@@ -178,27 +184,97 @@ public class PlatLogoActivity extends Activity {
        bg = new PBackground();
        layout.setBackground(bg);

        final ContentResolver cr = getContentResolver();

        layout.setOnTouchListener(new View.OnTouchListener() {
            final String TOUCH_STATS = "touch.stats";

            final PointerCoords pc0 = new PointerCoords();
            final PointerCoords pc1 = new PointerCoords();

            double pressure_min, pressure_max;
            int maxPointers;
            int tapCount;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                final float pressure = event.getPressure();
                switch (event.getActionMasked()) {
                    case MotionEvent.ACTION_DOWN:
                        pressure_min = pressure_max = pressure;
                        // fall through
                    case MotionEvent.ACTION_MOVE:
                        if (event.getPointerCount() > 1) {
                        if (pressure < pressure_min) pressure_min = pressure;
                        if (pressure > pressure_max) pressure_max = pressure;
                        final int pc = event.getPointerCount();
                        if (pc > maxPointers) maxPointers = pc;
                        if (pc > 1) {
                            event.getPointerCoords(0, pc0);
                            event.getPointerCoords(1, pc1);
                            bg.setRadius((float) Math.hypot(pc0.x - pc1.x, pc0.y - pc1.y) / 2f);
                        }
                        break;
                    case MotionEvent.ACTION_CANCEL:
                    case MotionEvent.ACTION_UP:
                        try {
                            final String touchDataJson = Settings.System.getString(cr, TOUCH_STATS);
                            final JSONObject touchData = new JSONObject(
                                    touchDataJson != null ? touchDataJson : "{}");
                            if (touchData.has("min")) {
                                pressure_min = Math.min(pressure_min, touchData.getDouble("min"));
                            }
                            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;
                }
                return true;
            }
        });
    }

    private void launchNextStage() {
        final ContentResolver cr = getContentResolver();

        if (Settings.System.getLong(cr, Settings.System.EGG_MODE, 0) == 0) {
            // For posterity: the moment this user unlocked the easter egg
            try {
                Settings.System.putLong(cr,
                        Settings.System.EGG_MODE,
                        System.currentTimeMillis());
            } catch (RuntimeException e) {
                Log.e("PlatLogoActivity", "Can't write settings", e);
            }
        }
        try {
            startActivity(new Intent(Intent.ACTION_MAIN)
                    .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_CLEAR_TASK)
                    .addCategory("com.android.internal.category.PLATLOGO"));
        } catch (ActivityNotFoundException ex) {
            Log.e("PlatLogoActivity", "No more eggs.");
        }
        finish();
    }

    @Override
    public void onStart() {
        super.onStart();
+33 −0
Original line number Diff line number Diff line
//
// 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.
//

android_app {
    // the build system in pi-dev can't quite handle R.java in kt
    // so we will have a mix of java and kotlin files
    srcs: ["src/**/*.java", "src/**/*.kt"],

    resource_dirs: ["res"],

    name: "EasterEgg",

    certificate: "platform",

	sdk_version: "current",

    optimize: {
        enabled: false,
    }
}

packages/EasterEgg/Android.mk

deleted100644 → 0
+0 −29
Original line number Diff line number Diff line
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_STATIC_JAVA_LIBRARIES := \
    jsr305

LOCAL_STATIC_ANDROID_LIBRARIES := \
    androidx.legacy_legacy-support-v4 \
    androidx.legacy_legacy-support-v13 \
    androidx.dynamicanimation_dynamicanimation \
    androidx.recyclerview_recyclerview \
    androidx.preference_preference \
    androidx.appcompat_appcompat \
    androidx.legacy_legacy-preference-v14

LOCAL_USE_AAPT2 := true

LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res

LOCAL_PACKAGE_NAME := EasterEgg
LOCAL_PRIVATE_PLATFORM_APIS := true
LOCAL_CERTIFICATE := platform

include $(BUILD_PACKAGE)

include $(call all-makefiles-under,$(LOCAL_PATH))
+17 −74
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2016 The Android Open Source Project
    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.
@@ -19,81 +19,24 @@ Copyright (C) 2016 The Android Open Source Project
    android:versionCode="1"
    android:versionName="1.0">

    <uses-sdk android:minSdkVersion="26" />
    <uses-sdk android:minSdkVersion="28" />

    <uses-permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application android:label="@string/app_name" android:icon="@drawable/icon">

        <activity android:name=".octo.Ocquarium"
            android:theme="@android:style/Theme.DeviceDefault.NoActionBar.Fullscreen"
    <application
        android:icon="@drawable/icon"
        android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="com.android.internal.category.PLATLOGO" />
            </intent-filter>
        </activity>

        <!-- Android N lives on inside Android O... -->

        <!-- Long press the QS tile to get here -->
        <activity android:name=".neko.NekoLand"
                  android:theme="@android:style/Theme.Material.NoActionBar"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.service.quicksettings.action.QS_TILE_PREFERENCES" />
                <action android:name="android.intent.action.MAIN" />
            </intent-filter>
        </activity>

        <!-- This is where the magic happens -->
        <service
            android:name=".neko.NekoService"
            android:enabled="true"
            android:permission="android.permission.BIND_JOB_SERVICE"
            android:exported="true" >
        </service>

        <!-- Used to show over lock screen -->
        <activity android:name=".neko.NekoLockedActivity"
                  android:excludeFromRecents="true"
                  android:theme="@android:style/Theme.Material.Light.Dialog.NoActionBar"
                  android:showOnLockScreen="true" />

        <!-- Used to enable easter egg -->
        <activity android:name=".neko.NekoActivationActivity"
            android:excludeFromRecents="true"
            android:theme="@android:style/Theme.NoDisplay"
            >
        <activity
            android:name=".paint.PaintActivity"
            android:configChanges="orientation|keyboardHidden|screenSize|uiMode"
            android:label="@string/app_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>

        <!-- The quick settings tile, disabled by default -->
        <service
            android:name=".neko.NekoTile"
            android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
            android:icon="@drawable/stat_icon"
            android:enabled="false"
            android:label="@string/default_tile_name">
            <intent-filter>
                <action android:name="android.service.quicksettings.action.QS_TILE" />
            </intent-filter>
        </service>

        <!-- FileProvider for sending pictures -->
        <provider
                android:name="androidx.core.content.FileProvider"
                android:authorities="com.android.egg.fileprovider"
                android:grantUriPermissions="true"
                android:exported="false">
            <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/filepaths" />
        </provider>
    </application>

</manifest>
+7 −9
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2016 The Android Open Source Project
    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.
@@ -13,10 +14,7 @@ Copyright (C) 2016 The Android Open Source Project
    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="48dp"
        android:height="48dp"
        android:viewportWidth="48.0"
        android:viewportHeight="48.0">
    <path android:name="leg1" android:fillColor="#FF000000" android:pathData="M9,37h5v6h-5z"/>
</vector>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="#FFFF3333" android:state_selected="true" />
    <item android:color="#FFFFFFFF" />
</selector>
 No newline at end of file
Loading