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 View view = new View(this) {
95 protected void onAttachedToWindow() {
96 super.onAttachedToWindow();
98 WallpaperManager wallpaperManager = (WallpaperManager) getSystemService(WALLPAPER_SERVICE);
99 wallpaperManager.setWallpaperOffsets(getWindowToken(), 0.5f, 0.5f);
101 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
102 DisplayInfo display = U.getDisplayInfo(HomeActivityDelegate.this);
103 wallpaperManager.suggestDesiredDimensions(display.width, display.height);
106 boolean shouldStartFreeformHack = shouldDelayFreeformHack && hits > 0;
107 shouldDelayFreeformHack = false;
109 if(shouldStartFreeformHack)
114 view.setOnClickListener(view1 -> LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU")));
116 view.setOnLongClickListener(view12 -> {
121 view.setOnGenericMotionListener((view13, motionEvent) -> {
122 if(motionEvent.getAction() == MotionEvent.ACTION_BUTTON_PRESS
123 && motionEvent.getButtonState() == MotionEvent.BUTTON_SECONDARY) {
129 final GestureDetector detector = new GestureDetector(this, new GestureDetector.OnGestureListener() {
131 public boolean onSingleTapUp(MotionEvent e) {
136 public void onShowPress(MotionEvent e) {}
139 public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
144 public void onLongPress(MotionEvent e) {}
147 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
152 public boolean onDown(MotionEvent e) {
157 detector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
159 public boolean onDoubleTap(MotionEvent e) {
160 final SharedPreferences pref = U.getSharedPreferences(HomeActivityDelegate.this);
161 if(!pref.getBoolean("dont_show_double_tap_dialog", false)) {
162 if(pref.getBoolean("double_tap_to_sleep", false)) {
163 U.lockDevice(HomeActivityDelegate.this);
165 AlertDialog.Builder builder = new AlertDialog.Builder(U.wrapContext(HomeActivityDelegate.this));
166 builder.setTitle(R.string.double_tap_to_sleep)
167 .setMessage(R.string.enable_double_tap_to_sleep)
168 .setNegativeButton(pref.getBoolean("double_tap_dialog_shown", false)
169 ? R.string.action_dont_show_again
170 : R.string.action_cancel, (dialog, which) -> pref.edit().putBoolean(pref.getBoolean("double_tap_dialog_shown", false)
171 ? "dont_show_double_tap_dialog"
172 : "double_tap_dialog_shown", true).apply())
173 .setPositiveButton(R.string.action_ok, (dialog, which) -> {
174 pref.edit().putBoolean("double_tap_to_sleep", true).apply();
175 U.lockDevice(HomeActivityDelegate.this);
178 AlertDialog dialog = builder.create();
187 public boolean onDoubleTapEvent(MotionEvent e) {
192 public boolean onSingleTapConfirmed(MotionEvent e) {
198 view.setOnTouchListener((v, event) -> {
199 detector.onTouchEvent(event);
203 if((this instanceof HomeActivity || U.isLauncherPermanentlyEnabled(this))
204 && !U.isChromeOs(this)) {
205 setContentView(view);
207 SharedPreferences pref = U.getSharedPreferences(this);
208 pref.edit().putBoolean("launcher", true).apply();
214 LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
215 lbm.registerReceiver(killReceiver, new IntentFilter("com.farmerbb.taskbar.KILL_HOME_ACTIVITY"));
216 lbm.registerReceiver(forceTaskbarStartReceiver, new IntentFilter("com.farmerbb.taskbar.FORCE_TASKBAR_RESTART"));
218 IntentFilter intentFilter = new IntentFilter();
219 intentFilter.addAction("com.farmerbb.taskbar.UPDATE_FREEFORM_CHECKBOX");
220 intentFilter.addAction("com.farmerbb.taskbar.TOUCH_ABSORBER_STATE_CHANGED");
222 lbm.registerReceiver(freeformToggleReceiver, intentFilter);
227 private void setWallpaper() {
228 if(U.shouldCollapse(this, true))
229 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.TEMP_HIDE_TASKBAR"));
231 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU"));
234 startActivity(Intent.createChooser(new Intent(Intent.ACTION_SET_WALLPAPER), getString(R.string.set_wallpaper)));
235 } catch (ActivityNotFoundException e) { /* Gracefully fail */ }
238 @SuppressWarnings("deprecation")
239 @TargetApi(Build.VERSION_CODES.N)
241 protected void onResume() {
244 if(bootToFreeform()) {
245 if(U.launcherIsDefault(this))
248 U.showToastLong(this, R.string.set_as_default_home);
250 Intent homeIntent = new Intent(Intent.ACTION_MAIN);
251 homeIntent.addCategory(Intent.CATEGORY_HOME);
252 homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
255 startActivity(homeIntent);
257 } catch (ActivityNotFoundException e) { /* Gracefully fail */ }
260 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.TEMP_SHOW_TASKBAR"));
265 protected void onStart() {
268 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU"));
270 if(U.canDrawOverlays(this)) {
271 if(!bootToFreeform()) {
272 final LauncherHelper helper = LauncherHelper.getInstance();
273 helper.setOnHomeScreen(true);
275 if(forceTaskbarStart) {
276 forceTaskbarStart = false;
277 new Handler().postDelayed(() -> {
278 helper.setOnHomeScreen(true);
283 } else if(U.launcherIsDefault(this))
286 dialog = U.showPermissionDialog(U.wrapContext(this),
287 () -> dialog = U.showErrorDialog(U.wrapContext(this), "SYSTEM_ALERT_WINDOW"),
291 private boolean bootToFreeform() {
292 SharedPreferences pref = U.getSharedPreferences(this);
293 return U.hasFreeformSupport(this)
294 && pref.getBoolean("freeform_hack", false)
295 && !U.isOverridingFreeformHack(this);
298 private void startTaskbar() {
299 SharedPreferences pref = U.getSharedPreferences(this);
300 if(pref.getBoolean("first_run", true)) {
301 SharedPreferences.Editor editor = pref.edit();
302 editor.putBoolean("first_run", false);
303 editor.putBoolean("collapsed", true);
306 dialog = U.showRecentAppsDialog(U.wrapContext(this),
307 () -> dialog = U.showErrorDialog(U.wrapContext(this), "GET_USAGE_STATS"),
311 // We always start the Taskbar and Start Menu services, even if the app isn't normally running
312 startService(new Intent(this, TaskbarService.class));
313 startService(new Intent(this, StartMenuService.class));
314 startService(new Intent(this, DashboardService.class));
316 if(pref.getBoolean("taskbar_active", false) && !U.isServiceRunning(this, NotificationService.class))
317 pref.edit().putBoolean("taskbar_active", false).apply();
319 // Show the Taskbar temporarily, as nothing else will be visible on screen
320 new Handler().postDelayed(() -> LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.TEMP_SHOW_TASKBAR")), 100);
323 private void startFreeformHack() {
324 if(shouldDelayFreeformHack)
327 U.startFreeformHack(this);
331 protected void onStop() {
334 SharedPreferences pref = U.getSharedPreferences(this);
335 if(!bootToFreeform()) {
336 LauncherHelper.getInstance().setOnHomeScreen(false);
338 if(U.shouldCollapse(this, true))
339 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.TEMP_HIDE_TASKBAR"));
341 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU"));
343 // Stop the Taskbar and Start Menu services if they should normally not be active
344 if(!pref.getBoolean("taskbar_active", false) || pref.getBoolean("is_hidden", false)) {
345 stopService(new Intent(this, TaskbarService.class));
346 stopService(new Intent(this, StartMenuService.class));
347 stopService(new Intent(this, DashboardService.class));
349 IconCache.getInstance(this).clearCache();
360 protected void onDestroy() {
363 LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
364 lbm.unregisterReceiver(killReceiver);
365 lbm.unregisterReceiver(forceTaskbarStartReceiver);
366 lbm.unregisterReceiver(freeformToggleReceiver);
370 public void onBackPressed() {
371 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU"));
374 private void killHomeActivity() {
375 LauncherHelper.getInstance().setOnHomeScreen(false);
377 // Stop the Taskbar and Start Menu services if they should normally not be active
378 SharedPreferences pref = U.getSharedPreferences(this);
379 if(!pref.getBoolean("taskbar_active", false) || pref.getBoolean("is_hidden", false)) {
380 stopService(new Intent(this, TaskbarService.class));
381 stopService(new Intent(this, StartMenuService.class));
382 stopService(new Intent(this, DashboardService.class));
384 IconCache.getInstance(this).clearCache();
386 U.stopFreeformHack(this);
392 private void updateWindowFlags() {
393 int flags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
394 if(FreeformHackHelper.getInstance().isTouchAbsorberActive() && U.isOverridingFreeformHack(this))
395 getWindow().setFlags(flags, flags);
397 getWindow().clearFlags(flags);