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.TargetApi;
19 import android.app.AlertDialog;
20 import android.app.FragmentTransaction;
21 import android.content.ActivityNotFoundException;
22 import android.content.BroadcastReceiver;
23 import android.content.ComponentName;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.content.IntentFilter;
27 import android.content.SharedPreferences;
28 import android.content.pm.PackageInfo;
29 import android.content.pm.PackageManager;
30 import android.content.pm.ShortcutInfo;
31 import android.content.pm.ShortcutManager;
32 import android.graphics.drawable.Icon;
33 import android.net.Uri;
34 import android.os.Build;
35 import android.os.Bundle;
36 import android.os.Handler;
37 import android.support.design.widget.Snackbar;
38 import android.support.v4.content.LocalBroadcastManager;
39 import android.support.v7.app.ActionBar;
40 import android.support.v7.app.AppCompatActivity;
41 import android.support.v7.widget.SwitchCompat;
43 import com.farmerbb.taskbar.BuildConfig;
44 import com.farmerbb.taskbar.R;
45 import com.farmerbb.taskbar.fragment.AboutFragment;
46 import com.farmerbb.taskbar.fragment.AppearanceFragment;
47 import com.farmerbb.taskbar.service.DashboardService;
48 import com.farmerbb.taskbar.service.NotificationService;
49 import com.farmerbb.taskbar.service.StartMenuService;
50 import com.farmerbb.taskbar.service.TaskbarService;
51 import com.farmerbb.taskbar.util.FreeformHackHelper;
52 import com.farmerbb.taskbar.util.IconCache;
53 import com.farmerbb.taskbar.util.LauncherHelper;
54 import com.farmerbb.taskbar.util.U;
57 import java.util.Arrays;
58 import java.util.Collections;
60 public class MainActivity extends AppCompatActivity {
62 private SwitchCompat theSwitch;
64 private BroadcastReceiver switchReceiver = new BroadcastReceiver() {
66 public void onReceive(Context context, Intent intent) {
71 private boolean hasCaption = false;
74 protected void onCreate(Bundle savedInstanceState) {
75 super.onCreate(savedInstanceState);
77 LocalBroadcastManager.getInstance(this).registerReceiver(switchReceiver, new IntentFilter("com.farmerbb.taskbar.UPDATE_SWITCH"));
79 final SharedPreferences pref = U.getSharedPreferences(this);
80 SharedPreferences.Editor editor = pref.edit();
82 switch(pref.getString("theme", "light")) {
84 setTheme(R.style.AppTheme);
87 setTheme(R.style.AppTheme_Dark);
91 if(pref.getBoolean("taskbar_active", false) && !U.isServiceRunning(this, NotificationService.class))
92 editor.putBoolean("taskbar_active", false);
94 // Ensure that components that should be enabled are enabled properly
95 boolean launcherEnabled = (pref.getBoolean("launcher", false) && U.canDrawOverlays(this))
96 || U.isLauncherPermanentlyEnabled(this);
98 editor.putBoolean("launcher", launcherEnabled);
101 ComponentName component = new ComponentName(this, HomeActivity.class);
102 getPackageManager().setComponentEnabledSetting(component,
103 launcherEnabled && !U.isDelegatingHomeActivity(this)
104 ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
105 : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
106 PackageManager.DONT_KILL_APP);
108 ComponentName component2 = new ComponentName(this, KeyboardShortcutActivity.class);
109 getPackageManager().setComponentEnabledSetting(component2,
110 pref.getBoolean("keyboard_shortcut", false)
111 ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
112 : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
113 PackageManager.DONT_KILL_APP);
115 ComponentName component3 = new ComponentName(this, ShortcutActivity.class);
116 getPackageManager().setComponentEnabledSetting(component3,
117 U.enableFreeformModeShortcut(this)
118 ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
119 : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
120 PackageManager.DONT_KILL_APP);
122 ComponentName component4 = new ComponentName(this, StartTaskbarActivity.class);
123 getPackageManager().setComponentEnabledSetting(component4,
124 PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
125 PackageManager.DONT_KILL_APP);
128 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.KILL_HOME_ACTIVITY"));
130 // Update caption state
131 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && U.isChromeOs(this)) {
132 getWindow().setRestrictedCaptionAreaListener(rect -> hasCaption = true);
134 new Handler().postDelayed(() -> pref.edit().putBoolean("has_caption", hasCaption).apply(), 500);
137 if(BuildConfig.APPLICATION_ID.equals(BuildConfig.PAID_APPLICATION_ID)) {
138 File file = new File(getFilesDir() + File.separator + "imported_successfully");
139 if(freeVersionInstalled() && !file.exists()) {
140 startActivity(new Intent(this, ImportSettingsActivity.class));
143 proceedWithAppLaunch(savedInstanceState);
145 proceedWithAppLaunch(savedInstanceState);
148 private boolean freeVersionInstalled() {
149 PackageManager pm = getPackageManager();
151 PackageInfo pInfo = pm.getPackageInfo(BuildConfig.BASE_APPLICATION_ID, 0);
152 return pInfo.versionCode >= 68
153 && pm.checkSignatures(BuildConfig.BASE_APPLICATION_ID, BuildConfig.APPLICATION_ID)
154 == PackageManager.SIGNATURE_MATCH;
155 } catch (PackageManager.NameNotFoundException e) {
160 private void proceedWithAppLaunch(Bundle savedInstanceState) {
161 setContentView(R.layout.main);
163 ActionBar actionBar = getSupportActionBar();
164 if(actionBar != null) {
165 actionBar.setCustomView(R.layout.switch_layout);
166 actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_CUSTOM);
169 theSwitch = findViewById(R.id.the_switch);
170 if(theSwitch != null) {
171 final SharedPreferences pref = U.getSharedPreferences(this);
172 theSwitch.setChecked(pref.getBoolean("taskbar_active", false));
174 theSwitch.setOnCheckedChangeListener((compoundButton, b) -> {
176 if(U.canDrawOverlays(this)) {
177 boolean firstRun = pref.getBoolean("first_run", true);
178 startTaskbarService();
181 U.showRecentAppsDialog(this);
183 U.showPermissionDialog(this);
184 compoundButton.setChecked(false);
187 stopTaskbarService();
191 if(savedInstanceState == null) {
194 if(!getIntent().hasExtra("theme_change"))
195 getFragmentManager().beginTransaction().replace(R.id.fragmentContainer, new AboutFragment(), "AboutFragment").commit();
197 getFragmentManager().beginTransaction().replace(R.id.fragmentContainer, new AppearanceFragment(), "AppearanceFragment").commit();
200 SharedPreferences pref = U.getSharedPreferences(this);
201 if(!BuildConfig.APPLICATION_ID.equals(BuildConfig.BASE_APPLICATION_ID) && freeVersionInstalled()) {
202 if(!pref.getBoolean("dont_show_uninstall_dialog", false)) {
203 AlertDialog.Builder builder = new AlertDialog.Builder(this);
204 builder.setTitle(R.string.settings_imported_successfully)
205 .setMessage(R.string.import_dialog_message)
206 .setPositiveButton(R.string.action_uninstall, (dialog, which) -> {
207 pref.edit().putBoolean("uninstall_dialog_shown", true).apply();
210 startActivity(new Intent(Intent.ACTION_DELETE, Uri.parse("package:" + BuildConfig.BASE_APPLICATION_ID)));
211 } catch (ActivityNotFoundException e) { /* Gracefully fail */ }
214 if(pref.getBoolean("uninstall_dialog_shown", false))
215 builder.setNegativeButton(R.string.action_dont_show_again, (dialogInterface, i) -> pref.edit().putBoolean("dont_show_uninstall_dialog", true).apply());
217 AlertDialog dialog = builder.create();
219 dialog.setCancelable(false);
222 if(!pref.getBoolean("uninstall_dialog_shown", false)) {
223 if(theSwitch != null) theSwitch.setChecked(false);
225 SharedPreferences.Editor editor = pref.edit();
227 String iconPack = pref.getString("icon_pack", BuildConfig.BASE_APPLICATION_ID);
228 if(iconPack.contains(BuildConfig.BASE_APPLICATION_ID)) {
229 editor.putString("icon_pack", BuildConfig.APPLICATION_ID);
231 U.refreshPinnedIcons(this);
234 editor.putBoolean("first_run", true);
239 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
240 ShortcutManager shortcutManager = getSystemService(ShortcutManager.class);
242 if(shortcutManager.getDynamicShortcuts().size() == 0) {
243 Intent intent = new Intent(Intent.ACTION_MAIN);
244 intent.setClass(this, StartTaskbarActivity.class);
245 intent.putExtra("is_launching_shortcut", true);
247 ShortcutInfo shortcut = new ShortcutInfo.Builder(this, "start_taskbar")
248 .setShortLabel(getString(R.string.start_taskbar))
249 .setIcon(Icon.createWithResource(this, R.drawable.shortcut_icon_start))
253 if(U.enableFreeformModeShortcut(this)) {
254 Intent intent2 = new Intent(Intent.ACTION_MAIN);
255 intent2.setClass(this, ShortcutActivity.class);
256 intent2.putExtra("is_launching_shortcut", true);
258 ShortcutInfo shortcut2 = new ShortcutInfo.Builder(this, "freeform_mode")
259 .setShortLabel(getString(R.string.pref_header_freeform))
260 .setIcon(Icon.createWithResource(this, R.drawable.shortcut_icon_freeform))
264 shortcutManager.setDynamicShortcuts(Arrays.asList(shortcut, shortcut2));
266 shortcutManager.setDynamicShortcuts(Collections.singletonList(shortcut));
270 if(pref.getBoolean("show_freeform_disabled_message", false)) {
271 Snackbar snackbar = Snackbar.make(
272 findViewById(R.id.main_activity_layout),
273 R.string.rip_freeform_snackbar,
274 Snackbar.LENGTH_INDEFINITE
277 snackbar.setAction(R.string.action_details, v -> {
280 AlertDialog.Builder builder = new AlertDialog.Builder(this);
281 builder.setTitle(R.string.pref_header_freeform)
282 .setMessage(R.string.rip_freeform_dialog)
283 .setPositiveButton(R.string.action_close, (dialog, which) ->
284 pref.edit().putBoolean("show_freeform_disabled_message", false).apply()
287 AlertDialog dialog = builder.create();
289 dialog.setCancelable(false);
297 protected void onResume() {
304 protected void onDestroy() {
305 LocalBroadcastManager.getInstance(this).unregisterReceiver(switchReceiver);
307 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && U.isChromeOs(this))
308 getWindow().setRestrictedCaptionAreaListener(null);
313 @SuppressWarnings("deprecation")
314 @TargetApi(Build.VERSION_CODES.N)
315 private void startTaskbarService() {
316 SharedPreferences pref = U.getSharedPreferences(this);
317 SharedPreferences.Editor editor = pref.edit();
319 editor.putBoolean("is_hidden", false);
321 if(pref.getBoolean("first_run", true)) {
322 editor.putBoolean("first_run", false);
323 editor.putBoolean("collapsed", true);
326 editor.putBoolean("taskbar_active", true);
327 editor.putLong("time_of_service_start", System.currentTimeMillis());
330 if(U.hasFreeformSupport(this)
331 && pref.getBoolean("freeform_hack", false)
332 && !FreeformHackHelper.getInstance().isFreeformHackActive()) {
333 U.startFreeformHack(this, true);
336 startService(new Intent(this, TaskbarService.class));
337 startService(new Intent(this, StartMenuService.class));
338 startService(new Intent(this, DashboardService.class));
339 startService(new Intent(this, NotificationService.class));
342 private void stopTaskbarService() {
343 SharedPreferences pref = U.getSharedPreferences(this);
344 pref.edit().putBoolean("taskbar_active", false).apply();
346 if(!LauncherHelper.getInstance().isOnHomeScreen()) {
347 stopService(new Intent(this, TaskbarService.class));
348 stopService(new Intent(this, StartMenuService.class));
349 stopService(new Intent(this, DashboardService.class));
351 IconCache.getInstance(this).clearCache();
353 LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("com.farmerbb.taskbar.START_MENU_DISAPPEARING"));
356 stopService(new Intent(this, NotificationService.class));
359 private void updateSwitch() {
360 if(theSwitch != null) {
361 SharedPreferences pref = U.getSharedPreferences(this);
362 theSwitch.setChecked(pref.getBoolean("taskbar_active", false));
367 public void onBackPressed() {
368 if(getFragmentManager().findFragmentById(R.id.fragmentContainer) instanceof AboutFragment)
369 super.onBackPressed();
373 .replace(R.id.fragmentContainer, new AboutFragment(), "AboutFragment")
374 .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE)