Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Rocket Launcher #446

Merged
merged 5 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

### v3.2.1

- Add Rocket Launcher Easter Egg
- Optimize the setting of theme logic
- Optimize APK file size
- Project modularization
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

### v3.2.1

- 添加 Rocket Launcher 彩蛋
- 优化设置主题逻辑
- 优化 APK 文件大小
- 项目模块化
Expand Down
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ dependencies {
implementation(project(":feature:crash"))
implementation(project(":feature:embedding-splits"))

implementation(project(":eggs:RocketLauncher"))
implementation(project(":eggs:AndroidNext"))
implementation(project(":eggs:VanillaIceCream"))
implementation(project(":eggs:UpsideDownCake"))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.dede.android_eggs.views.settings.compose.prefs

import android.content.Intent
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.AppRegistration
Expand All @@ -11,11 +14,14 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewmodel.compose.viewModel
import com.dede.android_eggs.R
import com.android.launcher2.RocketLauncher
import com.dede.android_eggs.util.LocalEvent
import com.dede.android_eggs.views.main.compose.EasterEggLogo
import com.dede.android_eggs.views.main.util.EasterEggHelp.VersionFormatter
import com.dede.android_eggs.views.settings.compose.basic.ExpandOptionsPref
import com.dede.android_eggs.views.settings.compose.basic.Option
import com.dede.android_eggs.views.settings.compose.basic.OptionShapes
import com.dede.android_eggs.views.settings.compose.basic.SettingPrefUtil
import com.dede.android_eggs.views.settings.compose.basic.SwitchOption
import com.dede.basic.provider.ComponentProvider
import dagger.hilt.android.lifecycle.HiltViewModel
Expand All @@ -33,16 +39,35 @@ fun ComponentManagerPref(viewModel: ComponentManagerViewModel = viewModel()) {
leadingIcon = Icons.Rounded.AppRegistration,
title = stringResource(id = StringsR.string.label_component_manager),
) {
val componentCount = componentList.size
val context = LocalContext.current
Option(
shape = OptionShapes.borderShape,
leadingIcon = {
EasterEggLogo(
res = com.android.launcher2.R.mipmap.ic_rocket_launcher,
modifier = Modifier.size(30.dp),
contentDescription = stringResource(id = com.android.launcher2.R.string.dream_name),
)
},
title = stringResource(com.android.launcher2.R.string.dream_name),
desc = stringResource(com.android.launcher2.R.string.rocket_launcher_desc),
onClick = {
context.startActivity(Intent(context, RocketLauncher::class.java))
LocalEvent.poster().post(SettingPrefUtil.ACTION_CLOSE_SETTING)
}
)

Spacer(modifier = Modifier.height(1.dp))

val componentCount = componentList.size
componentList.forEachIndexed { index, component ->
val formatter = VersionFormatter.create(component.apiLevelRange, component.nicknameRes)
SwitchOption(
shape = OptionShapes.indexOfShape(index = index, optionsCount = componentCount),
leadingIcon = {
EasterEggLogo(
res = component.iconRes,
modifier = Modifier.size(28.dp),
modifier = Modifier.size(30.dp),
contentDescription = stringResource(id = component.nameRes),
)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ object LocalEvent {

fun trimToSize(size: Int) {
var trimCount = 0
val keys = localEventLiveDataMap.keys
val keys = HashSet(localEventLiveDataMap.keys)
for (key in keys) {
val liveData = localEventLiveDataMap[key]
if (liveData == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ object AndroidNextEasterEgg : EasterEggProvider {
return ImageView(context).apply {
setImageDrawable(context.requireDrawable(PLATLOGO_RES))
setPadding(12.dp)
setBackgroundColor(0xFF_202124.toInt())
setBackgroundColor(0xFF_1B1E22.toInt())
}
}

Expand Down
1 change: 1 addition & 0 deletions eggs/RocketLauncher/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
7 changes: 7 additions & 0 deletions eggs/RocketLauncher/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
plugins {
id("easter.egg.library")
}

android {
namespace = "com.android.launcher2"
}
44 changes: 44 additions & 0 deletions eggs/RocketLauncher/lint-baseline.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<issues format="6" by="lint 8.5.0" type="baseline" client="gradle" dependencies="false" name="AGP (8.5.0)" variant="all" version="8.5.0">

<issue
id="DefaultLocale"
message="Implicitly using the default locale is a common source of bugs: Use `String.format(Locale, ...)` instead"
errorLine1=" return String.format(&quot;&lt;&apos;%s&apos; @ (%.1f, %.1f) v=%.1f a=%.1f dist/fuse=%.1f/%.1f>&quot;,"
errorLine2=" ^">
<location
file="src/main/java/com/android/launcher2/RocketLauncher.java"
line="175"
column="24"/>
</issue>

<issue
id="IconMissingDensityFolder"
message="Missing density variation folders in `src/main/res`: drawable-xxhdpi">
<location
file="src/main/res"/>
</issue>

<issue
id="ClickableViewAccessibility"
message="Custom view `FlyingIcon` overrides `onTouchEvent` but not `performClick`"
errorLine1=" public boolean onTouchEvent(MotionEvent event) {"
errorLine2=" ~~~~~~~~~~~~">
<location
file="src/main/java/com/android/launcher2/RocketLauncher.java"
line="116"
column="28"/>
</issue>

<issue
id="ClickableViewAccessibility"
message="Custom view `Board` overrides `onTouchEvent` but not `performClick`"
errorLine1=" public boolean onTouchEvent(MotionEvent event) {"
errorLine2=" ~~~~~~~~~~~~">
<location
file="src/main/java/com/android/launcher2/RocketLauncher.java"
line="413"
column="24"/>
</issue>

</issues>
34 changes: 34 additions & 0 deletions eggs/RocketLauncher/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<application>
<activity
android:name=".RocketLauncher"
android:exported="true"
android:icon="@mipmap/ic_rocket_launcher"
android:label="@string/dream_name"
android:roundIcon="@mipmap/ic_rocket_launcher_round"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.DREAM" />
</intent-filter>
</activity>

<service
android:name=".RocketLauncherDream"
android:exported="true"
android:icon="@mipmap/ic_rocket_launcher"
android:label="@string/dream_name"
android:permission="android.permission.BIND_DREAM_SERVICE"
android:roundIcon="@mipmap/ic_rocket_launcher_round">
<intent-filter>
<action android:name="android.service.dreams.DreamService" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>

</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package android.support.v13.dreams;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Canvas;
import android.os.BatteryManager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

import androidx.annotation.NonNull;

public class BasicDream extends Activity {
/** A simple Dream implementation that can be subclassed to write your own Dreams. Any Activity
* may be used as a Dream, so this class isn't strictly necessary. However, it does take care of
* a number of housekeeping tasks that most screensavers will want:
* <ul>
* <li>Keep the screen on as long as the device is plugged in
* <li>Exit (using <code>finish()</code>) as soon as any user activity is detected
* <li>Hide the system UI (courtesy its inner {@link BasicDreamView} class)
* </ul>
* Finally, it exposes an {@link BasicDream#onDraw(Canvas)} method that you can override to do
* your own drawing. As with a <code>View,</code> call {@link BasicDream#invalidate()} any time
* to request that a new frame be drawn.
*/
private final static String TAG = "BasicDream";
private final static boolean DEBUG = true;

private View mView;
private boolean mPlugged = false;

public class BasicDreamView extends View {
/** A simple view that just calls back to {@link BasicDream#onDraw(Canvas) onDraw} on its
* parent BasicDream Activity. It also hides the system UI if this feature is available on
* the current device.
*/
public BasicDreamView(Context c) {
super(c);
}

public BasicDreamView(Context c, AttributeSet at) {
super(c, at);
}

@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
setSystemUiVisibility(View.STATUS_BAR_HIDDEN);
}

@Override
public void onDraw(@NonNull Canvas c) {
BasicDream.this.onDraw(c);
}
}

private final BroadcastReceiver mPowerIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
// Only keep the screen on if we're plugged in.
boolean plugged = (1 == intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0));

if (plugged != mPlugged) {
if (DEBUG) Log.d(TAG, "now " + (plugged ? "plugged in" : "unplugged"));

mPlugged = plugged;
if (mPlugged) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
} else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
}
}
}
};

@Override
public void onStart() {
super.onStart();
setContentView(new BasicDreamView(this));
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
);
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(mPowerIntentReceiver, filter);
}

@Override
public void onPause() {
super.onPause();
// Anything that would pause this activity should probably end the screensaver.
if (DEBUG) Log.d(TAG, "exiting onPause");
finish();
}

@Override
public void onStop() {
super.onStop();
unregisterReceiver(mPowerIntentReceiver);
}

protected View getContentView() {
return mView;
}

@Override
public void setContentView(View v) {
super.setContentView(v);
mView = v;
}

protected void invalidate() {
getContentView().invalidate();
}

public void onDraw(Canvas c) {
}

public void onUserInteraction() {
if (DEBUG) Log.d(TAG, "exiting onUserInteraction");
finish();
}
}
Loading
Loading