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.service;
18 import android.accessibilityservice.AccessibilityService;
19 import android.annotation.SuppressLint;
20 import android.annotation.TargetApi;
21 import android.app.ActivityManager;
22 import android.app.AlarmManager;
23 import android.app.Service;
24 import android.app.usage.UsageEvents;
25 import android.app.usage.UsageStats;
26 import android.app.usage.UsageStatsManager;
27 import android.content.ActivityNotFoundException;
28 import android.content.BroadcastReceiver;
29 import android.content.Context;
30 import android.content.Intent;
31 import android.content.IntentFilter;
32 import android.content.SharedPreferences;
33 import android.content.pm.LauncherActivityInfo;
34 import android.content.pm.LauncherApps;
35 import android.content.pm.PackageManager;
36 import android.content.pm.ResolveInfo;
37 import android.content.res.Configuration;
38 import android.graphics.Color;
39 import android.graphics.PixelFormat;
40 import android.graphics.Point;
41 import android.graphics.Rect;
42 import android.graphics.Typeface;
43 import android.graphics.drawable.Drawable;
44 import android.os.Build;
45 import android.os.Handler;
46 import android.os.IBinder;
47 import android.os.PowerManager;
48 import android.os.SystemClock;
49 import android.os.UserHandle;
50 import android.os.UserManager;
51 import android.speech.RecognizerIntent;
52 import android.support.v4.content.ContextCompat;
53 import android.support.v4.graphics.ColorUtils;
54 import android.util.DisplayMetrics;
55 import android.view.Display;
56 import android.view.Gravity;
57 import android.view.LayoutInflater;
58 import android.view.MotionEvent;
59 import android.view.PointerIcon;
60 import android.view.View;
61 import android.view.ViewGroup;
62 import android.view.WindowManager;
63 import android.view.inputmethod.InputMethodManager;
64 import android.widget.Button;
65 import android.widget.FrameLayout;
66 import android.widget.ImageView;
68 import java.lang.reflect.Field;
69 import java.util.ArrayList;
70 import java.util.Collections;
71 import java.util.List;
73 import android.support.v4.content.LocalBroadcastManager;
74 import android.widget.LinearLayout;
75 import android.widget.Space;
77 import com.farmerbb.taskbar.BuildConfig;
78 import com.farmerbb.taskbar.activity.MainActivity;
79 import com.farmerbb.taskbar.R;
80 import com.farmerbb.taskbar.activity.ContextMenuActivity;
81 import com.farmerbb.taskbar.activity.dark.ContextMenuActivityDark;
82 import com.farmerbb.taskbar.activity.HomeActivity;
83 import com.farmerbb.taskbar.activity.InvisibleActivityFreeform;
84 import com.farmerbb.taskbar.util.AppEntry;
85 import com.farmerbb.taskbar.util.ApplicationType;
86 import com.farmerbb.taskbar.util.FreeformHackHelper;
87 import com.farmerbb.taskbar.util.IconCache;
88 import com.farmerbb.taskbar.util.LauncherHelper;
89 import com.farmerbb.taskbar.util.PinnedBlockedApps;
90 import com.farmerbb.taskbar.util.MenuHelper;
91 import com.farmerbb.taskbar.util.U;
93 public class TaskbarService extends Service {
95 private WindowManager windowManager;
96 private LinearLayout layout;
97 private ImageView startButton;
98 private LinearLayout taskbar;
99 private FrameLayout scrollView;
100 private Button button;
102 private FrameLayout dashboardButton;
103 private LinearLayout navbarButtons;
105 private Handler handler;
106 private Handler handler2;
107 private Thread thread;
108 private Thread thread2;
110 private boolean isShowingRecents = true;
111 private boolean shouldRefreshRecents = true;
112 private boolean taskbarShownTemporarily = false;
113 private boolean taskbarHiddenTemporarily = false;
114 private boolean isRefreshingRecents = false;
115 private boolean isFirstStart = true;
117 private boolean startThread2 = false;
118 private boolean stopThread2 = false;
120 private int refreshInterval = -1;
121 private long searchInterval = -1;
122 private String sortOrder = "false";
123 private boolean runningAppsOnly = false;
125 private int layoutId = R.layout.taskbar_left;
126 private int currentTaskbarPosition = 0;
127 private boolean showHideAutomagically = false;
128 private boolean positionIsVertical = false;
129 private boolean dashboardEnabled = false;
130 private boolean navbarButtonsEnabled = false;
132 private List<String> currentTaskbarIds = new ArrayList<>();
133 private int numOfPinnedApps = -1;
135 private View.OnClickListener ocl = view -> {
136 Intent intent = new Intent("com.farmerbb.taskbar.TOGGLE_START_MENU");
137 LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
140 private BroadcastReceiver showReceiver = new BroadcastReceiver() {
142 public void onReceive(Context context, Intent intent) {
147 private BroadcastReceiver hideReceiver = new BroadcastReceiver() {
149 public void onReceive(Context context, Intent intent) {
154 private BroadcastReceiver tempShowReceiver = new BroadcastReceiver() {
156 public void onReceive(Context context, Intent intent) {
161 private BroadcastReceiver tempHideReceiver = new BroadcastReceiver() {
163 public void onReceive(Context context, Intent intent) {
164 tempHideTaskbar(false);
168 private BroadcastReceiver startMenuAppearReceiver = new BroadcastReceiver() {
170 public void onReceive(Context context, Intent intent) {
171 if(startButton.getVisibility() == View.GONE
172 && (!LauncherHelper.getInstance().isOnHomeScreen() || FreeformHackHelper.getInstance().isInFreeformWorkspace()))
173 layout.setVisibility(View.GONE);
177 private BroadcastReceiver startMenuDisappearReceiver = new BroadcastReceiver() {
179 public void onReceive(Context context, Intent intent) {
180 if(startButton.getVisibility() == View.GONE)
181 layout.setVisibility(View.VISIBLE);
186 public IBinder onBind(Intent intent) {
191 public int onStartCommand(Intent intent, int flags, int startId) {
195 @TargetApi(Build.VERSION_CODES.M)
197 public void onCreate() {
200 SharedPreferences pref = U.getSharedPreferences(this);
201 if(pref.getBoolean("taskbar_active", false) || LauncherHelper.getInstance().isOnHomeScreen()) {
202 if(U.canDrawOverlays(this))
205 pref.edit().putBoolean("taskbar_active", false).apply();
212 @SuppressLint("RtlHardcoded")
213 private void drawTaskbar() {
214 IconCache.getInstance(this).clearCache();
216 // Initialize layout params
217 windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
218 U.setCachedRotation(windowManager.getDefaultDisplay().getRotation());
220 final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
221 WindowManager.LayoutParams.WRAP_CONTENT,
222 WindowManager.LayoutParams.WRAP_CONTENT,
224 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
225 PixelFormat.TRANSLUCENT);
227 // Determine where to show the taskbar on screen
228 switch(U.getTaskbarPosition(this)) {
230 layoutId = R.layout.taskbar_left;
231 params.gravity = Gravity.BOTTOM | Gravity.LEFT;
232 positionIsVertical = false;
234 case "bottom_vertical_left":
235 layoutId = R.layout.taskbar_vertical;
236 params.gravity = Gravity.BOTTOM | Gravity.LEFT;
237 positionIsVertical = true;
240 layoutId = R.layout.taskbar_right;
241 params.gravity = Gravity.BOTTOM | Gravity.RIGHT;
242 positionIsVertical = false;
244 case "bottom_vertical_right":
245 layoutId = R.layout.taskbar_vertical;
246 params.gravity = Gravity.BOTTOM | Gravity.RIGHT;
247 positionIsVertical = true;
250 layoutId = R.layout.taskbar_left;
251 params.gravity = Gravity.TOP | Gravity.LEFT;
252 positionIsVertical = false;
254 case "top_vertical_left":
255 layoutId = R.layout.taskbar_top_vertical;
256 params.gravity = Gravity.TOP | Gravity.LEFT;
257 positionIsVertical = true;
260 layoutId = R.layout.taskbar_right;
261 params.gravity = Gravity.TOP | Gravity.RIGHT;
262 positionIsVertical = false;
264 case "top_vertical_right":
265 layoutId = R.layout.taskbar_top_vertical;
266 params.gravity = Gravity.TOP | Gravity.RIGHT;
267 positionIsVertical = true;
272 SharedPreferences pref = U.getSharedPreferences(this);
273 boolean altButtonConfig = pref.getBoolean("alt_button_config", false);
275 layout = (LinearLayout) LayoutInflater.from(U.wrapContext(this)).inflate(layoutId, null);
276 taskbar = U.findViewById(layout, R.id.taskbar);
277 scrollView = U.findViewById(layout, R.id.taskbar_scrollview);
279 int backgroundTint = U.getBackgroundTint(this);
280 int accentColor = U.getAccentColor(this);
282 if(altButtonConfig) {
283 space = U.findViewById(layout, R.id.space_alt);
284 layout.findViewById(R.id.space).setVisibility(View.GONE);
286 space = U.findViewById(layout, R.id.space);
287 layout.findViewById(R.id.space_alt).setVisibility(View.GONE);
290 space.setOnClickListener(v -> toggleTaskbar(true));
292 startButton = U.findViewById(layout, R.id.start_button);
295 if(pref.getBoolean("app_drawer_icon", false)) {
298 if(U.isBlissOs(this)) {
299 drawable = ContextCompat.getDrawable(this, R.drawable.bliss);
300 drawable.setTint(accentColor);
302 drawable = ContextCompat.getDrawable(this, R.mipmap.ic_launcher);
304 startButton.setImageDrawable(drawable);
305 padding = getResources().getDimensionPixelSize(R.dimen.app_drawer_icon_padding_alt);
307 startButton.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.all_apps_button_icon));
308 padding = getResources().getDimensionPixelSize(R.dimen.app_drawer_icon_padding);
311 startButton.setPadding(padding, padding, padding, padding);
312 startButton.setOnClickListener(ocl);
313 startButton.setOnLongClickListener(view -> {
318 startButton.setOnGenericMotionListener((view, motionEvent) -> {
319 if(motionEvent.getAction() == MotionEvent.ACTION_BUTTON_PRESS
320 && motionEvent.getButtonState() == MotionEvent.BUTTON_SECONDARY)
326 refreshInterval = (int) (Float.parseFloat(pref.getString("refresh_frequency", "2")) * 1000);
327 if(refreshInterval == 0)
328 refreshInterval = 100;
330 sortOrder = pref.getString("sort_order", "false");
331 runningAppsOnly = pref.getString("recents_amount", "past_day").equals("running_apps_only");
333 switch(pref.getString("recents_amount", "past_day")) {
335 searchInterval = System.currentTimeMillis() - AlarmManager.INTERVAL_DAY;
338 long appStartTime = pref.getLong("time_of_service_start", System.currentTimeMillis());
339 long deviceStartTime = System.currentTimeMillis() - SystemClock.elapsedRealtime();
341 searchInterval = deviceStartTime > appStartTime ? deviceStartTime : appStartTime;
348 Intent intent = new Intent("com.farmerbb.taskbar.HIDE_START_MENU");
349 LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
351 if(altButtonConfig) {
352 button = U.findViewById(layout, R.id.hide_taskbar_button_alt);
353 layout.findViewById(R.id.hide_taskbar_button).setVisibility(View.GONE);
355 button = U.findViewById(layout, R.id.hide_taskbar_button);
356 layout.findViewById(R.id.hide_taskbar_button_alt).setVisibility(View.GONE);
360 button.setTypeface(Typeface.createFromFile("/system/fonts/Roboto-Regular.ttf"));
361 } catch (RuntimeException e) { /* Gracefully fail */ }
364 button.setOnClickListener(v -> toggleTaskbar(true));
366 LinearLayout buttonLayout = U.findViewById(layout, altButtonConfig
367 ? R.id.hide_taskbar_button_layout_alt
368 : R.id.hide_taskbar_button_layout);
369 if(buttonLayout != null) buttonLayout.setOnClickListener(v -> toggleTaskbar(true));
371 LinearLayout buttonLayoutToHide = U.findViewById(layout, altButtonConfig
372 ? R.id.hide_taskbar_button_layout
373 : R.id.hide_taskbar_button_layout_alt);
374 if(buttonLayoutToHide != null) buttonLayoutToHide.setVisibility(View.GONE);
376 dashboardButton = U.findViewById(layout, R.id.dashboard_button);
377 navbarButtons = U.findViewById(layout, R.id.navbar_buttons);
379 dashboardEnabled = pref.getBoolean("dashboard", false);
380 if(dashboardEnabled) {
381 layout.findViewById(R.id.square1).setBackgroundColor(accentColor);
382 layout.findViewById(R.id.square2).setBackgroundColor(accentColor);
383 layout.findViewById(R.id.square3).setBackgroundColor(accentColor);
384 layout.findViewById(R.id.square4).setBackgroundColor(accentColor);
385 layout.findViewById(R.id.square5).setBackgroundColor(accentColor);
386 layout.findViewById(R.id.square6).setBackgroundColor(accentColor);
388 dashboardButton.setOnClickListener(v -> LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.TOGGLE_DASHBOARD")));
390 dashboardButton.setVisibility(View.GONE);
392 if(pref.getBoolean("button_back", false)) {
393 navbarButtonsEnabled = true;
395 ImageView backButton = U.findViewById(layout, R.id.button_back);
396 backButton.setColorFilter(accentColor);
397 backButton.setVisibility(View.VISIBLE);
398 backButton.setOnClickListener(v -> {
399 U.sendAccessibilityAction(this, AccessibilityService.GLOBAL_ACTION_BACK);
400 if(U.shouldCollapse(this, false))
404 backButton.setOnLongClickListener(v -> {
405 InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
406 imm.showInputMethodPicker();
408 if(U.shouldCollapse(this, false))
414 backButton.setOnGenericMotionListener((view13, motionEvent) -> {
415 if(motionEvent.getAction() == MotionEvent.ACTION_BUTTON_PRESS
416 && motionEvent.getButtonState() == MotionEvent.BUTTON_SECONDARY) {
417 InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
418 imm.showInputMethodPicker();
420 if(U.shouldCollapse(this, false))
427 if(pref.getBoolean("button_home", false)) {
428 navbarButtonsEnabled = true;
430 ImageView homeButton = U.findViewById(layout, R.id.button_home);
431 homeButton.setColorFilter(accentColor);
432 homeButton.setVisibility(View.VISIBLE);
433 homeButton.setOnClickListener(v -> {
434 U.sendAccessibilityAction(this, AccessibilityService.GLOBAL_ACTION_HOME);
435 if(U.shouldCollapse(this, false))
439 homeButton.setOnLongClickListener(v -> {
440 Intent voiceSearchIntent = new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE);
441 voiceSearchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
444 startActivity(voiceSearchIntent);
445 } catch (ActivityNotFoundException e) { /* Gracefully fail */ }
447 if(U.shouldCollapse(this, false))
453 homeButton.setOnGenericMotionListener((view13, motionEvent) -> {
454 if(motionEvent.getAction() == MotionEvent.ACTION_BUTTON_PRESS
455 && motionEvent.getButtonState() == MotionEvent.BUTTON_SECONDARY) {
456 Intent voiceSearchIntent = new Intent(RecognizerIntent.ACTION_VOICE_SEARCH_HANDS_FREE);
457 voiceSearchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
460 startActivity(voiceSearchIntent);
461 } catch (ActivityNotFoundException e) { /* Gracefully fail */ }
463 if(U.shouldCollapse(this, false))
470 if(pref.getBoolean("button_recents", false)) {
471 navbarButtonsEnabled = true;
473 ImageView recentsButton = U.findViewById(layout, R.id.button_recents);
474 recentsButton.setColorFilter(accentColor);
475 recentsButton.setVisibility(View.VISIBLE);
476 recentsButton.setOnClickListener(v -> {
477 U.sendAccessibilityAction(this, AccessibilityService.GLOBAL_ACTION_RECENTS);
478 if(U.shouldCollapse(this, false))
482 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
483 recentsButton.setOnLongClickListener(v -> {
484 U.sendAccessibilityAction(this, AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN);
485 if(U.shouldCollapse(this, false))
491 recentsButton.setOnGenericMotionListener((view13, motionEvent) -> {
492 if(motionEvent.getAction() == MotionEvent.ACTION_BUTTON_PRESS
493 && motionEvent.getButtonState() == MotionEvent.BUTTON_SECONDARY) {
494 U.sendAccessibilityAction(this, AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN);
495 if(U.shouldCollapse(this, false))
503 if(!navbarButtonsEnabled)
504 navbarButtons.setVisibility(View.GONE);
506 layout.setBackgroundColor(backgroundTint);
507 layout.findViewById(R.id.divider).setBackgroundColor(accentColor);
508 button.setTextColor(accentColor);
510 if(isFirstStart && FreeformHackHelper.getInstance().isInFreeformWorkspace())
512 else if(!pref.getBoolean("collapsed", false) && pref.getBoolean("taskbar_active", false))
513 toggleTaskbar(false);
515 if(pref.getBoolean("auto_hide_navbar", false))
516 U.showHideNavigationBar(this, false);
518 LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
520 if(FreeformHackHelper.getInstance().isTouchAbsorberActive()) {
521 lbm.sendBroadcast(new Intent("com.farmerbb.taskbar.FINISH_FREEFORM_ACTIVITY"));
523 new Handler().postDelayed(() -> U.startTouchAbsorberActivity(this), 500);
526 lbm.unregisterReceiver(showReceiver);
527 lbm.unregisterReceiver(hideReceiver);
528 lbm.unregisterReceiver(tempShowReceiver);
529 lbm.unregisterReceiver(tempHideReceiver);
530 lbm.unregisterReceiver(startMenuAppearReceiver);
531 lbm.unregisterReceiver(startMenuDisappearReceiver);
533 lbm.registerReceiver(showReceiver, new IntentFilter("com.farmerbb.taskbar.SHOW_TASKBAR"));
534 lbm.registerReceiver(hideReceiver, new IntentFilter("com.farmerbb.taskbar.HIDE_TASKBAR"));
535 lbm.registerReceiver(tempShowReceiver, new IntentFilter("com.farmerbb.taskbar.TEMP_SHOW_TASKBAR"));
536 lbm.registerReceiver(tempHideReceiver, new IntentFilter("com.farmerbb.taskbar.TEMP_HIDE_TASKBAR"));
537 lbm.registerReceiver(startMenuAppearReceiver, new IntentFilter("com.farmerbb.taskbar.START_MENU_APPEARING"));
538 lbm.registerReceiver(startMenuDisappearReceiver, new IntentFilter("com.farmerbb.taskbar.START_MENU_DISAPPEARING"));
540 startRefreshingRecents();
542 windowManager.addView(layout, params);
544 isFirstStart = false;
547 private void startRefreshingRecents() {
548 if(thread != null) thread.interrupt();
551 SharedPreferences pref = U.getSharedPreferences(this);
552 showHideAutomagically = pref.getBoolean("hide_when_keyboard_shown", false);
554 currentTaskbarIds.clear();
556 handler = new Handler();
557 thread = new Thread(() -> {
558 updateRecentApps(true);
560 if(!isRefreshingRecents) {
561 isRefreshingRecents = true;
563 while(shouldRefreshRecents) {
564 SystemClock.sleep(refreshInterval);
565 updateRecentApps(false);
567 if(showHideAutomagically && !positionIsVertical && !MenuHelper.getInstance().isStartMenuOpen())
570 int[] location = new int[2];
571 layout.getLocationOnScreen(location);
573 if(location[1] != 0) {
574 if(location[1] > currentTaskbarPosition) {
575 currentTaskbarPosition = location[1];
576 } else if(location[1] < currentTaskbarPosition) {
577 if(currentTaskbarPosition - location[1] == getNavBarSize())
578 currentTaskbarPosition = location[1];
579 else if(!startThread2) {
581 tempHideTaskbar(true);
589 isRefreshingRecents = false;
596 @SuppressWarnings("Convert2streamapi")
597 @TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
598 private void updateRecentApps(final boolean firstRefresh) {
599 if(isScreenOff()) return;
601 SharedPreferences pref = U.getSharedPreferences(this);
602 final PackageManager pm = getPackageManager();
603 final List<AppEntry> entries = new ArrayList<>();
604 List<LauncherActivityInfo> launcherAppCache = new ArrayList<>();
605 int maxNumOfEntries = U.getMaxNumOfEntries(this);
606 int realNumOfPinnedApps = 0;
607 boolean fullLength = pref.getBoolean("full_length", false);
609 PinnedBlockedApps pba = PinnedBlockedApps.getInstance(this);
610 List<AppEntry> pinnedApps = pba.getPinnedApps();
611 List<AppEntry> blockedApps = pba.getBlockedApps();
612 List<String> applicationIdsToRemove = new ArrayList<>();
614 // Filter out anything on the pinned/blocked apps lists
615 if(pinnedApps.size() > 0) {
616 UserManager userManager = (UserManager) getSystemService(USER_SERVICE);
617 LauncherApps launcherApps = (LauncherApps) getSystemService(LAUNCHER_APPS_SERVICE);
619 for(AppEntry entry : pinnedApps) {
620 boolean packageEnabled = launcherApps.isPackageEnabled(entry.getPackageName(),
621 userManager.getUserForSerialNumber(entry.getUserId(this)));
626 realNumOfPinnedApps--;
628 applicationIdsToRemove.add(entry.getPackageName());
631 realNumOfPinnedApps = realNumOfPinnedApps + pinnedApps.size();
634 if(blockedApps.size() > 0) {
635 for(AppEntry entry : blockedApps) {
636 applicationIdsToRemove.add(entry.getPackageName());
640 // Get list of all recently used apps
641 List<AppEntry> usageStatsList = realNumOfPinnedApps < maxNumOfEntries ? getAppEntries() : new ArrayList<>();
642 if(usageStatsList.size() > 0 || realNumOfPinnedApps > 0 || fullLength) {
643 if(realNumOfPinnedApps < maxNumOfEntries) {
644 List<AppEntry> usageStatsList2 = new ArrayList<>();
645 List<AppEntry> usageStatsList3 = new ArrayList<>();
646 List<AppEntry> usageStatsList4 = new ArrayList<>();
647 List<AppEntry> usageStatsList5 = new ArrayList<>();
648 List<AppEntry> usageStatsList6;
650 Intent homeIntent = new Intent(Intent.ACTION_MAIN);
651 homeIntent.addCategory(Intent.CATEGORY_HOME);
652 ResolveInfo defaultLauncher = pm.resolveActivity(homeIntent, PackageManager.MATCH_DEFAULT_ONLY);
654 // Filter out apps without a launcher intent
655 // Also filter out the current launcher, and Taskbar itself
656 for(AppEntry packageInfo : usageStatsList) {
657 if(hasLauncherIntent(packageInfo.getPackageName())
658 && !packageInfo.getPackageName().contains(BuildConfig.BASE_APPLICATION_ID)
659 && !packageInfo.getPackageName().equals(defaultLauncher.activityInfo.packageName))
660 usageStatsList2.add(packageInfo);
663 // Filter out apps that don't fall within our current search interval
664 for(AppEntry stats : usageStatsList2) {
665 if(stats.getLastTimeUsed() > searchInterval || runningAppsOnly)
666 usageStatsList3.add(stats);
669 // Sort apps by either most recently used, or most time used
670 if(!runningAppsOnly && sortOrder.contains("most_used")) {
671 Collections.sort(usageStatsList3, (us1, us2) -> Long.compare(us2.getTotalTimeInForeground(), us1.getTotalTimeInForeground()));
673 Collections.sort(usageStatsList3, (us1, us2) -> Long.compare(us2.getLastTimeUsed(), us1.getLastTimeUsed()));
676 // Filter out any duplicate entries
677 List<String> applicationIds = new ArrayList<>();
678 for(AppEntry stats : usageStatsList3) {
679 if(!applicationIds.contains(stats.getPackageName())) {
680 usageStatsList4.add(stats);
681 applicationIds.add(stats.getPackageName());
685 // Filter out the currently running foreground app, if requested by the user
686 if(pref.getBoolean("hide_foreground", false)) {
687 UsageStatsManager mUsageStatsManager = (UsageStatsManager) getSystemService(USAGE_STATS_SERVICE);
688 UsageEvents events = mUsageStatsManager.queryEvents(searchInterval, System.currentTimeMillis());
689 UsageEvents.Event eventCache = new UsageEvents.Event();
690 String currentForegroundApp = null;
692 while(events.hasNextEvent()) {
693 events.getNextEvent(eventCache);
695 if(eventCache.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
696 if(!(eventCache.getPackageName().contains(BuildConfig.BASE_APPLICATION_ID)
697 && !eventCache.getClassName().equals(MainActivity.class.getCanonicalName())
698 && !eventCache.getClassName().equals(HomeActivity.class.getCanonicalName())
699 && !eventCache.getClassName().equals(InvisibleActivityFreeform.class.getCanonicalName())))
700 currentForegroundApp = eventCache.getPackageName();
704 if(!applicationIdsToRemove.contains(currentForegroundApp))
705 applicationIdsToRemove.add(currentForegroundApp);
708 for(AppEntry stats : usageStatsList4) {
709 if(!applicationIdsToRemove.contains(stats.getPackageName())) {
710 usageStatsList5.add(stats);
714 // Truncate list to a maximum length
715 if(usageStatsList5.size() > maxNumOfEntries)
716 usageStatsList6 = usageStatsList5.subList(0, maxNumOfEntries);
718 usageStatsList6 = usageStatsList5;
720 // Determine if we need to reverse the order
721 boolean needToReverseOrder;
722 switch(U.getTaskbarPosition(this)) {
725 needToReverseOrder = sortOrder.contains("false");
728 needToReverseOrder = sortOrder.contains("true");
732 if(needToReverseOrder) {
733 Collections.reverse(usageStatsList6);
736 // Generate the AppEntries for TaskbarAdapter
737 int number = usageStatsList6.size() == maxNumOfEntries
738 ? usageStatsList6.size() - realNumOfPinnedApps
739 : usageStatsList6.size();
741 UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
742 LauncherApps launcherApps = (LauncherApps) getSystemService(Context.LAUNCHER_APPS_SERVICE);
744 final List<UserHandle> userHandles = userManager.getUserProfiles();
746 for(int i = 0; i < number; i++) {
747 for(UserHandle handle : userHandles) {
748 String packageName = usageStatsList6.get(i).getPackageName();
749 List<LauncherActivityInfo> list = launcherApps.getActivityList(packageName, handle);
750 if(!list.isEmpty()) {
751 // Google App workaround
752 if(!packageName.equals("com.google.android.googlequicksearchbox"))
753 launcherAppCache.add(list.get(0));
755 boolean added = false;
756 for(LauncherActivityInfo info : list) {
757 if(info.getName().equals("com.google.android.googlequicksearchbox.SearchActivity")) {
758 launcherAppCache.add(info);
763 if(!added) launcherAppCache.add(list.get(0));
766 AppEntry newEntry = new AppEntry(
774 newEntry.setUserId(userManager.getSerialNumberForUser(handle));
775 entries.add(newEntry);
783 while(entries.size() > maxNumOfEntries) {
785 entries.remove(entries.size() - 1);
786 launcherAppCache.remove(launcherAppCache.size() - 1);
787 } catch (ArrayIndexOutOfBoundsException e) { /* Gracefully fail */ }
790 // Determine if we need to reverse the order again
791 if(U.getTaskbarPosition(this).contains("vertical")) {
792 Collections.reverse(entries);
793 Collections.reverse(launcherAppCache);
796 // Now that we've generated the list of apps,
797 // we need to determine if we need to redraw the Taskbar or not
798 boolean shouldRedrawTaskbar = firstRefresh;
800 List<String> finalApplicationIds = new ArrayList<>();
801 for(AppEntry entry : entries) {
802 finalApplicationIds.add(entry.getPackageName());
805 if(finalApplicationIds.size() != currentTaskbarIds.size()
806 || numOfPinnedApps != realNumOfPinnedApps)
807 shouldRedrawTaskbar = true;
809 for(int i = 0; i < finalApplicationIds.size(); i++) {
810 if(!finalApplicationIds.get(i).equals(currentTaskbarIds.get(i))) {
811 shouldRedrawTaskbar = true;
817 if(shouldRedrawTaskbar) {
818 currentTaskbarIds = finalApplicationIds;
819 numOfPinnedApps = realNumOfPinnedApps;
821 UserManager userManager = (UserManager) getSystemService(USER_SERVICE);
823 int launcherAppCachePos = -1;
824 for(int i = 0; i < entries.size(); i++) {
825 if(entries.get(i).getComponentName() == null) {
826 launcherAppCachePos++;
827 LauncherActivityInfo appInfo = launcherAppCache.get(launcherAppCachePos);
828 String packageName = entries.get(i).getPackageName();
832 AppEntry newEntry = new AppEntry(
834 appInfo.getComponentName().flattenToString(),
835 appInfo.getLabel().toString(),
836 IconCache.getInstance(this).getIcon(this, pm, appInfo),
839 newEntry.setUserId(userManager.getSerialNumberForUser(appInfo.getUser()));
840 entries.add(i, newEntry);
844 final int numOfEntries = Math.min(entries.size(), maxNumOfEntries);
847 if(numOfEntries > 0 || fullLength) {
848 ViewGroup.LayoutParams params = scrollView.getLayoutParams();
849 DisplayMetrics metrics = U.getRealDisplayMetrics(this);
850 int recentsSize = getResources().getDimensionPixelSize(R.dimen.icon_size) * numOfEntries;
851 float maxRecentsSize = fullLength ? Float.MAX_VALUE : recentsSize;
853 if(U.getTaskbarPosition(this).contains("vertical")) {
854 int maxScreenSize = metrics.heightPixels
855 - U.getStatusBarHeight(this)
856 - U.getBaseTaskbarSize(this);
858 params.height = (int) Math.min(maxRecentsSize, maxScreenSize)
859 + getResources().getDimensionPixelSize(R.dimen.divider_size);
861 if(fullLength && U.getTaskbarPosition(this).contains("bottom")) {
863 Space whitespace = U.findViewById(layout, R.id.whitespace);
864 ViewGroup.LayoutParams params2 = whitespace.getLayoutParams();
865 params2.height = maxScreenSize - recentsSize;
866 whitespace.setLayoutParams(params2);
867 } catch (NullPointerException e) { /* Gracefully fail */ }
870 int maxScreenSize = metrics.widthPixels
871 - U.getBaseTaskbarSize(this);
873 params.width = (int) Math.min(maxRecentsSize, maxScreenSize)
874 + getResources().getDimensionPixelSize(R.dimen.divider_size);
876 if(fullLength && U.getTaskbarPosition(this).contains("right")) {
878 Space whitespace = U.findViewById(layout, R.id.whitespace);
879 ViewGroup.LayoutParams params2 = whitespace.getLayoutParams();
880 params2.width = maxScreenSize - recentsSize;
881 whitespace.setLayoutParams(params2);
882 } catch (NullPointerException e) { /* Gracefully fail */ }
886 scrollView.setLayoutParams(params);
888 taskbar.removeAllViews();
889 for(int i = 0; i < entries.size(); i++) {
890 taskbar.addView(getView(entries, i));
893 isShowingRecents = true;
894 if(shouldRefreshRecents && scrollView.getVisibility() != View.VISIBLE) {
896 scrollView.setVisibility(View.INVISIBLE);
898 scrollView.setVisibility(View.VISIBLE);
901 if(firstRefresh && scrollView.getVisibility() != View.VISIBLE)
902 new Handler().post(() -> {
903 switch(U.getTaskbarPosition(this)) {
908 if(sortOrder.contains("false"))
909 scrollView.scrollTo(0, 0);
910 else if(sortOrder.contains("true"))
911 scrollView.scrollTo(taskbar.getWidth(), taskbar.getHeight());
913 case "bottom_vertical_left":
914 case "bottom_vertical_right":
915 case "top_vertical_left":
916 case "top_vertical_right":
917 if(sortOrder.contains("false"))
918 scrollView.scrollTo(taskbar.getWidth(), taskbar.getHeight());
919 else if(sortOrder.contains("true"))
920 scrollView.scrollTo(0, 0);
924 if(shouldRefreshRecents) {
925 scrollView.setVisibility(View.VISIBLE);
929 isShowingRecents = false;
930 scrollView.setVisibility(View.GONE);
934 } else if(firstRefresh || currentTaskbarIds.size() > 0) {
935 currentTaskbarIds.clear();
937 isShowingRecents = false;
938 scrollView.setVisibility(View.GONE);
943 private void toggleTaskbar(boolean userInitiated) {
944 if(userInitiated && Build.BRAND.equalsIgnoreCase("essential")) {
945 SharedPreferences pref = U.getSharedPreferences(this);
946 if(!pref.getBoolean("grip_rejection_toast_shown", false)) {
947 U.showToastLong(this, R.string.essential_phone_grip_rejection);
948 pref.edit().putBoolean("grip_rejection_toast_shown", true).apply();
952 if(startButton.getVisibility() == View.GONE)
958 private void showTaskbar(boolean clearVariables) {
960 taskbarShownTemporarily = false;
961 taskbarHiddenTemporarily = false;
964 if(startButton.getVisibility() == View.GONE) {
965 startButton.setVisibility(View.VISIBLE);
966 space.setVisibility(View.VISIBLE);
969 dashboardButton.setVisibility(View.VISIBLE);
971 if(navbarButtonsEnabled)
972 navbarButtons.setVisibility(View.VISIBLE);
974 if(isShowingRecents && scrollView.getVisibility() == View.GONE)
975 scrollView.setVisibility(View.INVISIBLE);
977 shouldRefreshRecents = true;
978 startRefreshingRecents();
980 SharedPreferences pref = U.getSharedPreferences(this);
981 pref.edit().putBoolean("collapsed", true).apply();
985 new Handler().post(() -> LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.SHOW_START_MENU_SPACE")));
989 private void hideTaskbar(boolean clearVariables) {
991 taskbarShownTemporarily = false;
992 taskbarHiddenTemporarily = false;
995 if(startButton.getVisibility() == View.VISIBLE) {
996 startButton.setVisibility(View.GONE);
997 space.setVisibility(View.GONE);
1000 dashboardButton.setVisibility(View.GONE);
1002 if(navbarButtonsEnabled)
1003 navbarButtons.setVisibility(View.GONE);
1005 if(isShowingRecents) {
1006 scrollView.setVisibility(View.GONE);
1009 shouldRefreshRecents = false;
1010 if(thread != null) thread.interrupt();
1012 SharedPreferences pref = U.getSharedPreferences(this);
1013 pref.edit().putBoolean("collapsed", false).apply();
1017 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU"));
1018 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_DASHBOARD"));
1020 new Handler().post(() -> LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU_SPACE")));
1024 private void tempShowTaskbar() {
1025 if(!taskbarHiddenTemporarily) {
1026 SharedPreferences pref = U.getSharedPreferences(this);
1027 if(!pref.getBoolean("collapsed", false)) taskbarShownTemporarily = true;
1032 if(taskbarHiddenTemporarily)
1033 taskbarHiddenTemporarily = false;
1036 private void tempHideTaskbar(boolean monitorPositionChanges) {
1037 if(!taskbarShownTemporarily) {
1038 SharedPreferences pref = U.getSharedPreferences(this);
1039 if(pref.getBoolean("collapsed", false)) taskbarHiddenTemporarily = true;
1044 if(taskbarShownTemporarily)
1045 taskbarShownTemporarily = false;
1047 if(monitorPositionChanges && showHideAutomagically && !positionIsVertical) {
1048 if(thread2 != null) thread2.interrupt();
1050 handler2 = new Handler();
1051 thread2 = new Thread(() -> {
1052 stopThread2 = false;
1054 while(!stopThread2) {
1055 SystemClock.sleep(refreshInterval);
1057 handler2.post(() -> stopThread2 = checkPositionChange());
1060 startThread2 = false;
1067 private boolean checkPositionChange() {
1068 if(!isScreenOff() && layout != null) {
1069 int[] location = new int[2];
1070 layout.getLocationOnScreen(location);
1072 if(location[1] == 0) {
1075 if(location[1] > currentTaskbarPosition) {
1076 currentTaskbarPosition = location[1];
1077 if(taskbarHiddenTemporarily) {
1081 } else if(location[1] == currentTaskbarPosition && taskbarHiddenTemporarily) {
1084 } else if(location[1] < currentTaskbarPosition
1085 && currentTaskbarPosition - location[1] == getNavBarSize()) {
1086 currentTaskbarPosition = location[1];
1094 private int getNavBarSize() {
1095 Point size = new Point();
1096 Point realSize = new Point();
1098 WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
1099 Display display = wm.getDefaultDisplay();
1100 display.getSize(size);
1101 display.getRealSize(realSize);
1103 return realSize.y - size.y;
1107 public void onDestroy() {
1108 shouldRefreshRecents = false;
1113 windowManager.removeView(layout);
1114 } catch (IllegalArgumentException e) { /* Gracefully fail */ }
1116 SharedPreferences pref = U.getSharedPreferences(this);
1117 if(pref.getBoolean("skip_auto_hide_navbar", false)) {
1118 pref.edit().remove("skip_auto_hide_navbar").apply();
1119 } else if(pref.getBoolean("auto_hide_navbar", false))
1120 U.showHideNavigationBar(this, true);
1122 LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
1124 lbm.unregisterReceiver(showReceiver);
1125 lbm.unregisterReceiver(hideReceiver);
1126 lbm.unregisterReceiver(tempShowReceiver);
1127 lbm.unregisterReceiver(tempHideReceiver);
1128 lbm.unregisterReceiver(startMenuAppearReceiver);
1129 lbm.unregisterReceiver(startMenuDisappearReceiver);
1131 isFirstStart = true;
1134 @SuppressWarnings("deprecation")
1135 private void openContextMenu() {
1136 SharedPreferences pref = U.getSharedPreferences(this);
1137 Intent intent = null;
1139 switch(pref.getString("theme", "light")) {
1141 intent = new Intent(this, ContextMenuActivity.class);
1144 intent = new Intent(this, ContextMenuActivityDark.class);
1148 if(intent != null) {
1149 intent.putExtra("dont_show_quit", LauncherHelper.getInstance().isOnHomeScreen() && !pref.getBoolean("taskbar_active", false));
1150 intent.putExtra("is_start_button", true);
1151 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1154 if(U.hasFreeformSupport(this) && FreeformHackHelper.getInstance().isInFreeformWorkspace()) {
1155 DisplayMetrics metrics = U.getRealDisplayMetrics(this);
1157 if(intent != null && U.hasBrokenSetLaunchBoundsApi())
1158 intent.putExtra("context_menu_fix", true);
1160 startActivity(intent,
1161 U.getActivityOptions(this, ApplicationType.CONTEXT_MENU)
1163 new Rect(0, 0, metrics.widthPixels, metrics.heightPixels)
1166 startActivity(intent);
1169 private void updateButton(boolean isCollapsed) {
1170 SharedPreferences pref = U.getSharedPreferences(this);
1171 boolean hide = pref.getBoolean("invisible_button", false);
1173 if(button != null) button.setText(getString(isCollapsed ? R.string.right_arrow : R.string.left_arrow));
1174 if(layout != null) layout.setAlpha(isCollapsed && hide ? 0 : 1);
1177 @TargetApi(Build.VERSION_CODES.M)
1179 public void onConfigurationChanged(Configuration newConfig) {
1180 super.onConfigurationChanged(newConfig);
1182 if(layout != null) {
1184 windowManager.removeView(layout);
1185 } catch (IllegalArgumentException e) { /* Gracefully fail */ }
1187 currentTaskbarPosition = 0;
1189 if(U.canDrawOverlays(this))
1192 SharedPreferences pref = U.getSharedPreferences(this);
1193 pref.edit().putBoolean("taskbar_active", false).apply();
1200 private View getView(List<AppEntry> list, int position) {
1201 View convertView = View.inflate(this, R.layout.icon, null);
1203 final AppEntry entry = list.get(position);
1204 final SharedPreferences pref = U.getSharedPreferences(this);
1206 ImageView imageView = U.findViewById(convertView, R.id.icon);
1207 ImageView imageView2 = U.findViewById(convertView, R.id.shortcut_icon);
1208 imageView.setImageDrawable(entry.getIcon(this));
1209 imageView2.setBackgroundColor(pref.getInt("accent_color", getResources().getInteger(R.integer.translucent_white)));
1211 String taskbarPosition = U.getTaskbarPosition(this);
1212 if(pref.getBoolean("shortcut_icon", true)) {
1213 boolean shouldShowShortcutIcon;
1214 if(taskbarPosition.contains("vertical"))
1215 shouldShowShortcutIcon = position >= list.size() - numOfPinnedApps;
1217 shouldShowShortcutIcon = position < numOfPinnedApps;
1219 if(shouldShowShortcutIcon) imageView2.setVisibility(View.VISIBLE);
1222 if(taskbarPosition.equals("bottom_right") || taskbarPosition.equals("top_right")) {
1223 imageView.setRotationY(180);
1224 imageView2.setRotationY(180);
1227 FrameLayout layout = U.findViewById(convertView, R.id.entry);
1228 layout.setOnClickListener(view -> U.launchApp(this, entry.getPackageName(), entry.getComponentName(), entry.getUserId(this), null, true, false));
1230 layout.setOnLongClickListener(view -> {
1231 int[] location = new int[2];
1232 view.getLocationOnScreen(location);
1233 openContextMenu(entry, location);
1237 layout.setOnGenericMotionListener((view, motionEvent) -> {
1238 int action = motionEvent.getAction();
1240 if(action == MotionEvent.ACTION_BUTTON_PRESS
1241 && motionEvent.getButtonState() == MotionEvent.BUTTON_SECONDARY) {
1242 int[] location = new int[2];
1243 view.getLocationOnScreen(location);
1244 openContextMenu(entry, location);
1247 if(action == MotionEvent.ACTION_SCROLL && pref.getBoolean("visual_feedback", true))
1248 view.setBackgroundColor(0);
1253 if(pref.getBoolean("visual_feedback", true)) {
1254 layout.setOnHoverListener((v, event) -> {
1255 if(event.getAction() == MotionEvent.ACTION_HOVER_ENTER) {
1256 int accentColor = U.getAccentColor(this);
1257 accentColor = ColorUtils.setAlphaComponent(accentColor, Color.alpha(accentColor) / 2);
1258 v.setBackgroundColor(accentColor);
1261 if(event.getAction() == MotionEvent.ACTION_HOVER_EXIT)
1262 v.setBackgroundColor(0);
1264 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
1265 v.setPointerIcon(PointerIcon.getSystemIcon(this, PointerIcon.TYPE_DEFAULT));
1270 layout.setOnTouchListener((v, event) -> {
1271 v.setAlpha(event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE ? 0.5f : 1);
1279 @SuppressWarnings("deprecation")
1280 private void openContextMenu(AppEntry entry, int[] location) {
1281 SharedPreferences pref = U.getSharedPreferences(this);
1282 Intent intent = null;
1284 switch(pref.getString("theme", "light")) {
1286 intent = new Intent(this, ContextMenuActivity.class);
1289 intent = new Intent(this, ContextMenuActivityDark.class);
1293 if(intent != null) {
1294 intent.putExtra("package_name", entry.getPackageName());
1295 intent.putExtra("app_name", entry.getLabel());
1296 intent.putExtra("component_name", entry.getComponentName());
1297 intent.putExtra("user_id", entry.getUserId(this));
1298 intent.putExtra("x", location[0]);
1299 intent.putExtra("y", location[1]);
1300 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1303 if(U.hasFreeformSupport(this) && FreeformHackHelper.getInstance().isInFreeformWorkspace()) {
1304 DisplayMetrics metrics = U.getRealDisplayMetrics(this);
1306 if(intent != null && U.hasBrokenSetLaunchBoundsApi())
1307 intent.putExtra("context_menu_fix", true);
1309 startActivity(intent,
1310 U.getActivityOptions(this, ApplicationType.CONTEXT_MENU)
1312 new Rect(0, 0, metrics.widthPixels, metrics.heightPixels)
1315 startActivity(intent);
1318 private List<AppEntry> getAppEntries() {
1319 SharedPreferences pref = U.getSharedPreferences(this);
1321 return getAppEntriesUsingActivityManager(Integer.parseInt(pref.getString("max_num_of_recents", "10")));
1323 return getAppEntriesUsingUsageStats();
1326 @SuppressWarnings("deprecation")
1327 @TargetApi(Build.VERSION_CODES.M)
1328 private List<AppEntry> getAppEntriesUsingActivityManager(int maxNum) {
1329 ActivityManager mActivityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
1330 List<ActivityManager.RecentTaskInfo> usageStatsList = mActivityManager.getRecentTasks(maxNum, 0);
1331 List<AppEntry> entries = new ArrayList<>();
1333 for(int i = 0; i < usageStatsList.size(); i++) {
1334 ActivityManager.RecentTaskInfo recentTaskInfo = usageStatsList.get(i);
1335 if(recentTaskInfo.id != -1) {
1336 String packageName = recentTaskInfo.baseActivity.getPackageName();
1337 AppEntry newEntry = new AppEntry(
1346 Field field = ActivityManager.RecentTaskInfo.class.getField("firstActiveTime");
1347 newEntry.setLastTimeUsed(field.getLong(recentTaskInfo));
1348 } catch (Exception e) {
1349 newEntry.setLastTimeUsed(i);
1352 entries.add(newEntry);
1359 @TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
1360 private List<AppEntry> getAppEntriesUsingUsageStats() {
1361 UsageStatsManager mUsageStatsManager = (UsageStatsManager) getSystemService(USAGE_STATS_SERVICE);
1362 List<UsageStats> usageStatsList = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, searchInterval, System.currentTimeMillis());
1363 List<AppEntry> entries = new ArrayList<>();
1365 for(UsageStats usageStats : usageStatsList) {
1366 AppEntry newEntry = new AppEntry(
1367 usageStats.getPackageName(),
1374 newEntry.setTotalTimeInForeground(usageStats.getTotalTimeInForeground());
1375 newEntry.setLastTimeUsed(usageStats.getLastTimeUsed());
1376 entries.add(newEntry);
1382 private boolean hasLauncherIntent(String packageName) {
1383 Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
1384 intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
1385 intentToResolve.setPackage(packageName);
1387 List<ResolveInfo> ris = getPackageManager().queryIntentActivities(intentToResolve, 0);
1388 return ris != null && ris.size() > 0;
1391 private boolean isScreenOff() {
1392 if(U.isChromeOs(this))
1395 PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
1396 return !pm.isInteractive();