1 /* Copyright 2016 Braden Farmer
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 package com.farmerbb.taskbar.activity;
18 import android.annotation.SuppressLint;
19 import android.annotation.TargetApi;
20 import android.app.Activity;
21 import android.app.AlertDialog;
22 import android.app.WallpaperManager;
23 import android.content.ActivityNotFoundException;
24 import android.content.BroadcastReceiver;
25 import android.content.Context;
26 import android.content.Intent;
27 import android.content.IntentFilter;
28 import android.content.SharedPreferences;
29 import android.os.Build;
30 import android.os.Bundle;
31 import android.os.Handler;
32 import android.support.v4.content.LocalBroadcastManager;
33 import android.view.GestureDetector;
34 import android.view.MotionEvent;
35 import android.view.View;
36 import android.view.WindowManager;
38 import com.farmerbb.taskbar.R;
39 import com.farmerbb.taskbar.service.DashboardService;
40 import com.farmerbb.taskbar.service.NotificationService;
41 import com.farmerbb.taskbar.service.StartMenuService;
42 import com.farmerbb.taskbar.service.TaskbarService;
43 import com.farmerbb.taskbar.util.CompatUtils;
44 import com.farmerbb.taskbar.util.DisplayInfo;
45 import com.farmerbb.taskbar.util.FreeformHackHelper;
46 import com.farmerbb.taskbar.util.IconCache;
47 import com.farmerbb.taskbar.util.LauncherHelper;
48 import com.farmerbb.taskbar.util.U;
50 public class HomeActivityDelegate extends Activity {
52 private boolean forceTaskbarStart = false;
53 private AlertDialog dialog;
55 private boolean shouldDelayFreeformHack;
58 private BroadcastReceiver killReceiver = new BroadcastReceiver() {
60 public void onReceive(Context context, Intent intent) {
65 private BroadcastReceiver forceTaskbarStartReceiver = new BroadcastReceiver() {
67 public void onReceive(Context context, Intent intent) {
68 forceTaskbarStart = true;
72 private BroadcastReceiver freeformToggleReceiver = new BroadcastReceiver() {
74 public void onReceive(Context context, Intent intent) {
79 @SuppressLint("RestrictedApi")
81 protected void onCreate(Bundle savedInstanceState) {
82 super.onCreate(savedInstanceState);
84 shouldDelayFreeformHack = true;
87 WindowManager.LayoutParams params = getWindow().getAttributes();
88 if(CompatUtils.applyDisplayCutoutModeTo(params))
89 getWindow().setAttributes(params);
91 getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
93 SharedPreferences pref = U.getSharedPreferences(this);
95 View view = new View(this) {
97 protected void onAttachedToWindow() {
98 super.onAttachedToWindow();
100 WallpaperManager wallpaperManager = (WallpaperManager) getSystemService(WALLPAPER_SERVICE);
101 wallpaperManager.setWallpaperOffsets(getWindowToken(), 0.5f, 0.5f);
103 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
104 DisplayInfo display = U.getDisplayInfo(HomeActivityDelegate.this);
105 wallpaperManager.suggestDesiredDimensions(display.width, display.height);
108 boolean shouldStartFreeformHack = shouldDelayFreeformHack && hits > 0;
109 shouldDelayFreeformHack = false;
111 if(shouldStartFreeformHack)
116 view.setOnClickListener(view1 -> LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU")));
118 view.setOnLongClickListener(view2 -> {
119 if(!pref.getBoolean("freeform_hack", false))
125 view.setOnGenericMotionListener((view3, motionEvent) -> {
126 if(motionEvent.getAction() == MotionEvent.ACTION_BUTTON_PRESS
127 && motionEvent.getButtonState() == MotionEvent.BUTTON_SECONDARY
128 && !pref.getBoolean("freeform_hack", false))
134 final GestureDetector detector = new GestureDetector(this, new GestureDetector.OnGestureListener() {
136 public boolean onSingleTapUp(MotionEvent e) {
141 public void onShowPress(MotionEvent e) {}
144 public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
149 public void onLongPress(MotionEvent e) {}
152 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
157 public boolean onDown(MotionEvent e) {
162 detector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
164 public boolean onDoubleTap(MotionEvent e) {
165 if(!pref.getBoolean("dont_show_double_tap_dialog", false)) {
166 if(pref.getBoolean("double_tap_to_sleep", false)) {
167 U.lockDevice(HomeActivityDelegate.this);
169 AlertDialog.Builder builder = new AlertDialog.Builder(U.wrapContext(HomeActivityDelegate.this));
170 builder.setTitle(R.string.double_tap_to_sleep)
171 .setMessage(R.string.enable_double_tap_to_sleep)
172 .setNegativeButton(pref.getBoolean("double_tap_dialog_shown", false)
173 ? R.string.action_dont_show_again
174 : R.string.action_cancel, (dialog, which) -> pref.edit().putBoolean(pref.getBoolean("double_tap_dialog_shown", false)
175 ? "dont_show_double_tap_dialog"
176 : "double_tap_dialog_shown", true).apply())
177 .setPositiveButton(R.string.action_ok, (dialog, which) -> {
178 pref.edit().putBoolean("double_tap_to_sleep", true).apply();
179 U.lockDevice(HomeActivityDelegate.this);
182 AlertDialog dialog = builder.create();
191 public boolean onDoubleTapEvent(MotionEvent e) {
196 public boolean onSingleTapConfirmed(MotionEvent e) {
202 view.setOnTouchListener((v, event) -> {
203 if(!pref.getBoolean("freeform_hack", false))
204 detector.onTouchEvent(event);
209 if((this instanceof HomeActivity || U.isLauncherPermanentlyEnabled(this))
210 && !U.isChromeOs(this)) {
211 setContentView(view);
212 pref.edit().putBoolean("launcher", true).apply();
218 LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
219 lbm.registerReceiver(killReceiver, new IntentFilter("com.farmerbb.taskbar.KILL_HOME_ACTIVITY"));
220 lbm.registerReceiver(forceTaskbarStartReceiver, new IntentFilter("com.farmerbb.taskbar.FORCE_TASKBAR_RESTART"));
222 IntentFilter intentFilter = new IntentFilter();
223 intentFilter.addAction("com.farmerbb.taskbar.UPDATE_FREEFORM_CHECKBOX");
224 intentFilter.addAction("com.farmerbb.taskbar.TOUCH_ABSORBER_STATE_CHANGED");
226 lbm.registerReceiver(freeformToggleReceiver, intentFilter);
231 private void setWallpaper() {
232 if(U.shouldCollapse(this, true))
233 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.TEMP_HIDE_TASKBAR"));
235 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU"));
238 startActivity(Intent.createChooser(new Intent(Intent.ACTION_SET_WALLPAPER), getString(R.string.set_wallpaper)));
239 } catch (ActivityNotFoundException e) { /* Gracefully fail */ }
242 @SuppressWarnings("deprecation")
243 @TargetApi(Build.VERSION_CODES.N)
245 protected void onResume() {
248 if(bootToFreeform()) {
249 if(U.launcherIsDefault(this))
252 U.showToastLong(this, R.string.set_as_default_home);
254 Intent homeIntent = new Intent(Intent.ACTION_MAIN);
255 homeIntent.addCategory(Intent.CATEGORY_HOME);
256 homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
259 startActivity(homeIntent);
261 } catch (ActivityNotFoundException e) { /* Gracefully fail */ }
264 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.TEMP_SHOW_TASKBAR"));
269 protected void onStart() {
272 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU"));
274 if(U.canDrawOverlays(this)) {
275 if(!bootToFreeform()) {
276 final LauncherHelper helper = LauncherHelper.getInstance();
277 helper.setOnHomeScreen(true);
279 if(forceTaskbarStart) {
280 forceTaskbarStart = false;
281 new Handler().postDelayed(() -> {
282 helper.setOnHomeScreen(true);
287 } else if(U.launcherIsDefault(this))
290 dialog = U.showPermissionDialog(U.wrapContext(this),
291 () -> dialog = U.showErrorDialog(U.wrapContext(this), "SYSTEM_ALERT_WINDOW"),
295 private boolean bootToFreeform() {
296 SharedPreferences pref = U.getSharedPreferences(this);
297 return U.hasFreeformSupport(this)
298 && pref.getBoolean("freeform_hack", false)
299 && !U.isOverridingFreeformHack(this);
302 private void startTaskbar() {
303 SharedPreferences pref = U.getSharedPreferences(this);
304 if(pref.getBoolean("first_run", true)) {
305 SharedPreferences.Editor editor = pref.edit();
306 editor.putBoolean("first_run", false);
307 editor.putBoolean("collapsed", true);
310 dialog = U.showRecentAppsDialog(U.wrapContext(this),
311 () -> dialog = U.showErrorDialog(U.wrapContext(this), "GET_USAGE_STATS"),
315 // We always start the Taskbar and Start Menu services, even if the app isn't normally running
316 startService(new Intent(this, TaskbarService.class));
317 startService(new Intent(this, StartMenuService.class));
318 startService(new Intent(this, DashboardService.class));
320 if(pref.getBoolean("taskbar_active", false) && !U.isServiceRunning(this, NotificationService.class))
321 pref.edit().putBoolean("taskbar_active", false).apply();
323 // Show the Taskbar temporarily, as nothing else will be visible on screen
324 new Handler().postDelayed(() -> LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.TEMP_SHOW_TASKBAR")), 100);
327 private void startFreeformHack() {
328 if(shouldDelayFreeformHack)
331 U.startFreeformHack(this);
335 protected void onStop() {
338 SharedPreferences pref = U.getSharedPreferences(this);
339 if(!bootToFreeform()) {
340 LauncherHelper.getInstance().setOnHomeScreen(false);
342 if(U.shouldCollapse(this, true))
343 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.TEMP_HIDE_TASKBAR"));
345 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU"));
347 // Stop the Taskbar and Start Menu services if they should normally not be active
348 if(!pref.getBoolean("taskbar_active", false) || pref.getBoolean("is_hidden", false)) {
349 stopService(new Intent(this, TaskbarService.class));
350 stopService(new Intent(this, StartMenuService.class));
351 stopService(new Intent(this, DashboardService.class));
353 IconCache.getInstance(this).clearCache();
364 protected void onDestroy() {
367 LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
368 lbm.unregisterReceiver(killReceiver);
369 lbm.unregisterReceiver(forceTaskbarStartReceiver);
370 lbm.unregisterReceiver(freeformToggleReceiver);
374 public void onBackPressed() {
375 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU"));
378 private void killHomeActivity() {
379 LauncherHelper.getInstance().setOnHomeScreen(false);
381 // Stop the Taskbar and Start Menu services if they should normally not be active
382 SharedPreferences pref = U.getSharedPreferences(this);
383 if(!pref.getBoolean("taskbar_active", false) || pref.getBoolean("is_hidden", false)) {
384 stopService(new Intent(this, TaskbarService.class));
385 stopService(new Intent(this, StartMenuService.class));
386 stopService(new Intent(this, DashboardService.class));
388 IconCache.getInstance(this).clearCache();
390 U.stopFreeformHack(this);
396 private void updateWindowFlags() {
397 int flags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
398 if(FreeformHackHelper.getInstance().isTouchAbsorberActive() && U.isOverridingFreeformHack(this))
399 getWindow().setFlags(flags, flags);
401 getWindow().clearFlags(flags);