OSDN Git Service

Abstract out the code for drawing the taskbar, start menu, and dashboard UI away...
[android-x86/packages-apps-Taskbar.git] / app / src / main / java / com / farmerbb / taskbar / ui / DashboardController.java
1 /* Based on code by Leonardo Fischer
2  * See https://github.com/lgfischer/WidgetHostExample
3  *
4  * Copyright 2016 Braden Farmer
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 package com.farmerbb.taskbar.ui;
20
21 import android.animation.Animator;
22 import android.animation.AnimatorListenerAdapter;
23 import android.annotation.SuppressLint;
24 import android.annotation.TargetApi;
25 import android.appwidget.AppWidgetHost;
26 import android.appwidget.AppWidgetHostView;
27 import android.appwidget.AppWidgetManager;
28 import android.appwidget.AppWidgetProviderInfo;
29 import android.content.BroadcastReceiver;
30 import android.content.ComponentName;
31 import android.content.Context;
32 import android.content.Intent;
33 import android.content.IntentFilter;
34 import android.content.SharedPreferences;
35 import android.content.pm.PackageManager;
36 import android.content.res.Configuration;
37 import android.graphics.Color;
38 import android.graphics.ColorMatrix;
39 import android.graphics.ColorMatrixColorFilter;
40 import android.graphics.drawable.Drawable;
41 import android.os.Build;
42 import android.os.Bundle;
43 import android.os.Handler;
44 import android.os.Process;
45 import android.support.v4.content.LocalBroadcastManager;
46 import android.support.v4.graphics.ColorUtils;
47 import android.util.SparseArray;
48 import android.view.MotionEvent;
49 import android.view.PointerIcon;
50 import android.view.View;
51 import android.view.ViewGroup;
52 import android.view.WindowManager;
53 import android.widget.FrameLayout;
54 import android.widget.ImageView;
55 import android.widget.LinearLayout;
56 import android.widget.TextView;
57 import android.widget.Toast;
58
59 import com.farmerbb.taskbar.R;
60 import com.farmerbb.taskbar.activity.DashboardActivity;
61 import com.farmerbb.taskbar.activity.dark.DashboardActivityDark;
62 import com.farmerbb.taskbar.util.DashboardHelper;
63 import com.farmerbb.taskbar.widget.DashboardCell;
64 import com.farmerbb.taskbar.util.FreeformHackHelper;
65 import com.farmerbb.taskbar.util.LauncherHelper;
66 import com.farmerbb.taskbar.util.U;
67
68 import java.util.List;
69
70 public class DashboardController implements Controller {
71
72     private AppWidgetManager mAppWidgetManager;
73     private AppWidgetHost mAppWidgetHost;
74
75     private Context context;
76     private LinearLayout layout;
77
78     private SparseArray<DashboardCell> cells = new SparseArray<>();
79     private SparseArray<AppWidgetHostView> widgets = new SparseArray<>();
80
81     private final int APPWIDGET_HOST_ID = 123;
82
83     private int columns;
84     private int rows;
85     private int maxSize;
86     private int previouslySelectedCell = -1;
87
88     private View.OnClickListener ocl = view -> toggleDashboard();
89
90     private View.OnClickListener cellOcl = view -> cellClick(view, true);
91
92     private View.OnHoverListener cellOhl = (v, event) -> {
93         cellClick(v, false);
94
95         if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
96             v.setPointerIcon(PointerIcon.getSystemIcon(context, PointerIcon.TYPE_DEFAULT));
97
98         return false;
99     };
100
101     private View.OnLongClickListener olcl = v -> {
102         cellLongClick(v);
103         return true;
104     };
105
106     private View.OnGenericMotionListener ogml = (view, motionEvent) -> {
107         if(motionEvent.getAction() == MotionEvent.ACTION_BUTTON_PRESS
108                 && motionEvent.getButtonState() == MotionEvent.BUTTON_SECONDARY)
109             cellLongClick(view);
110
111         return false;
112     };
113
114     private DashboardCell.OnInterceptedLongPressListener listener = this::cellLongClick;
115
116     private BroadcastReceiver toggleReceiver = new BroadcastReceiver() {
117         @Override
118         public void onReceive(Context context, Intent intent) {
119             toggleDashboard();
120         }
121     };
122
123     private BroadcastReceiver addWidgetReceiver = new BroadcastReceiver() {
124         @Override
125         public void onReceive(Context context, Intent intent) {
126             fadeIn();
127
128             if(intent.hasExtra("appWidgetId") && intent.hasExtra("cellId")) {
129                 int appWidgetId = intent.getExtras().getInt("appWidgetId", -1);
130                 int cellId = intent.getExtras().getInt("cellId", -1);
131
132                 addWidget(appWidgetId, cellId, true);
133             }
134         }
135     };
136
137     private BroadcastReceiver removeWidgetReceiver = new BroadcastReceiver() {
138         @Override
139         public void onReceive(Context context, Intent intent) {
140             fadeIn();
141
142             if(intent.hasExtra("cellId")) {
143                 int cellId = intent.getExtras().getInt("cellId", -1);
144
145                 removeWidget(cellId, false);
146             }
147         }
148     };
149
150     private BroadcastReceiver hideReceiver = new BroadcastReceiver() {
151         @Override
152         public void onReceive(Context context, Intent intent) {
153             hideDashboard();
154         }
155     };
156
157     public DashboardController(Context context) {
158         this.context = context;
159     }
160
161     @TargetApi(Build.VERSION_CODES.M)
162     @Override
163     public void onCreateHost(Host host) {
164         SharedPreferences pref = U.getSharedPreferences(context);
165         if(pref.getBoolean("dashboard", false)) {
166             if(pref.getBoolean("taskbar_active", false) || LauncherHelper.getInstance().isOnHomeScreen()) {
167                 if(U.canDrawOverlays(context))
168                     drawDashboard(host);
169                 else {
170                     pref.edit().putBoolean("taskbar_active", false).apply();
171
172                     host.terminate();
173                 }
174             } else host.terminate();
175         } else host.terminate();
176     }
177
178     @SuppressLint("RtlHardcoded")
179     private void drawDashboard(Host host) {
180         final ViewParams params = new ViewParams(
181                 WindowManager.LayoutParams.MATCH_PARENT,
182                 WindowManager.LayoutParams.MATCH_PARENT,
183                 -1,
184                 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
185         );
186
187         // Initialize views
188         layout = new LinearLayout(context);
189         layout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
190         layout.setVisibility(View.GONE);
191         layout.setAlpha(0);
192
193         SharedPreferences pref = U.getSharedPreferences(context);
194         int width = pref.getInt("dashboard_width", context.getApplicationContext().getResources().getInteger(R.integer.dashboard_width));
195         int height = pref.getInt("dashboard_height", context.getApplicationContext().getResources().getInteger(R.integer.dashboard_height));
196
197         boolean isPortrait = context.getApplicationContext().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
198         boolean isLandscape = context.getApplicationContext().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
199
200         if(isPortrait) {
201             columns = height;
202             rows = width;
203         }
204
205         if(isLandscape) {
206             columns = width;
207             rows = height;
208         }
209
210         maxSize = columns * rows;
211
212         int backgroundTint = U.getBackgroundTint(context);
213         int accentColor = U.getAccentColor(context);
214         int accentColorAlt = accentColor;
215         accentColorAlt = ColorUtils.setAlphaComponent(accentColorAlt, Color.alpha(accentColorAlt) / 2);
216
217         int cellCount = 0;
218
219         for(int i = 0; i < columns; i++) {
220             LinearLayout layout2 = new LinearLayout(context);
221             layout2.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 1));
222             layout2.setOrientation(LinearLayout.VERTICAL);
223
224             for(int j = 0; j < rows; j++) {
225                 DashboardCell cellLayout = (DashboardCell) View.inflate(context, R.layout.dashboard, null);
226                 cellLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 1));
227                 cellLayout.setBackgroundColor(backgroundTint);
228                 cellLayout.setOnClickListener(cellOcl);
229                 cellLayout.setOnHoverListener(cellOhl);
230
231                 TextView empty = cellLayout.findViewById(R.id.empty);
232                 empty.setBackgroundColor(accentColorAlt);
233                 empty.setTextColor(accentColor);
234
235                 Bundle bundle = new Bundle();
236                 bundle.putInt("cellId", cellCount);
237
238                 cellLayout.setTag(bundle);
239                 cells.put(cellCount, cellLayout);
240                 cellCount++;
241
242                 layout2.addView(cellLayout);
243             }
244
245             layout.addView(layout2);
246         }
247
248         mAppWidgetManager = AppWidgetManager.getInstance(context);
249         mAppWidgetHost = new AppWidgetHost(context, APPWIDGET_HOST_ID);
250         mAppWidgetHost.startListening();
251
252         for(int i = 0; i < maxSize; i++) {
253             int appWidgetId = pref.getInt("dashboard_widget_" + i, -1);
254             if(appWidgetId != -1)
255                 addWidget(appWidgetId, i, false);
256             else if(pref.getBoolean("dashboard_widget_" + i + "_placeholder", false))
257                 addPlaceholder(i);
258         }
259
260         mAppWidgetHost.stopListening();
261
262         LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context);
263
264         lbm.unregisterReceiver(toggleReceiver);
265         lbm.unregisterReceiver(addWidgetReceiver);
266         lbm.unregisterReceiver(removeWidgetReceiver);
267         lbm.unregisterReceiver(hideReceiver);
268
269         lbm.registerReceiver(toggleReceiver, new IntentFilter("com.farmerbb.taskbar.TOGGLE_DASHBOARD"));
270         lbm.registerReceiver(addWidgetReceiver, new IntentFilter("com.farmerbb.taskbar.ADD_WIDGET_COMPLETED"));
271         lbm.registerReceiver(removeWidgetReceiver, new IntentFilter("com.farmerbb.taskbar.REMOVE_WIDGET_COMPLETED"));
272         lbm.registerReceiver(hideReceiver, new IntentFilter("com.farmerbb.taskbar.HIDE_DASHBOARD"));
273
274         host.addView(layout, params);
275
276         new Handler().postDelayed(() -> {
277             int paddingSize = context.getResources().getDimensionPixelSize(R.dimen.icon_size);
278
279             switch(U.getTaskbarPosition(context)) {
280                 case "top_vertical_left":
281                 case "bottom_vertical_left":
282                     layout.setPadding(paddingSize, 0, 0, 0);
283                     break;
284                 case "top_left":
285                 case "top_right":
286                     layout.setPadding(0, paddingSize, 0, 0);
287                     break;
288                 case "top_vertical_right":
289                 case "bottom_vertical_right":
290                     layout.setPadding(0, 0, paddingSize, 0);
291                     break;
292                 case "bottom_left":
293                 case "bottom_right":
294                     layout.setPadding(0, 0, 0, paddingSize);
295                     break;
296             }
297         }, 100);
298     }
299
300     private void toggleDashboard() {
301         if(layout.getVisibility() == View.GONE)
302             showDashboard();
303         else
304             hideDashboard();
305     }
306
307     @SuppressWarnings("deprecation")
308     @TargetApi(Build.VERSION_CODES.N)
309     private void showDashboard() {
310         if(layout.getVisibility() == View.GONE) {
311             layout.setOnClickListener(ocl);
312             fadeIn();
313
314             LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.DASHBOARD_APPEARING"));
315             LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.HIDE_START_MENU"));
316
317             boolean inFreeformMode = FreeformHackHelper.getInstance().isInFreeformWorkspace();
318
319             final SharedPreferences pref = U.getSharedPreferences(context);
320             Intent intent = null;
321
322             switch(pref.getString("theme", "light")) {
323                 case "light":
324                     intent = new Intent(context, DashboardActivity.class);
325                     break;
326                 case "dark":
327                     intent = new Intent(context, DashboardActivityDark.class);
328                     break;
329             }
330
331             if(intent != null) {
332                 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
333                 intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
334             }
335
336             if(inFreeformMode) {
337                 if(intent != null && U.hasBrokenSetLaunchBoundsApi())
338                     intent.putExtra("context_menu_fix", true);
339
340                 U.startActivityMaximized(context, intent);
341             } else
342                 context.startActivity(intent);
343
344             for(int i = 0; i < maxSize; i++) {
345                 final DashboardCell cellLayout = cells.get(i);
346                 final AppWidgetHostView hostView = widgets.get(i);
347
348                 if(hostView != null) {
349                     try {
350                         context.getPackageManager().getApplicationInfo(hostView.getAppWidgetInfo().provider.getPackageName(), 0);
351                         hostView.post(() -> {
352                             ViewGroup.LayoutParams params = hostView.getLayoutParams();
353                             params.width = cellLayout.getWidth();
354                             params.height = cellLayout.getHeight();
355                             hostView.setLayoutParams(params);
356                             hostView.updateAppWidgetSize(null, cellLayout.getWidth(), cellLayout.getHeight(), cellLayout.getWidth(), cellLayout.getHeight());
357                         });
358                     } catch (PackageManager.NameNotFoundException e) {
359                         removeWidget(i, false);
360                     } catch (NullPointerException e) {
361                         removeWidget(i, true);
362                     }
363                 }
364             }
365
366             if(!pref.getBoolean("dashboard_tutorial_shown", false)) {
367                 U.showToastLong(context, R.string.dashboard_tutorial);
368                 pref.edit().putBoolean("dashboard_tutorial_shown", true).apply();
369             }
370         }
371     }
372
373     private void hideDashboard() {
374         if(layout.getVisibility() == View.VISIBLE) {
375             layout.setOnClickListener(null);
376             fadeOut(true);
377
378             for(int i = 0; i < maxSize; i++) {
379                 FrameLayout frameLayout = cells.get(i);
380                 frameLayout.findViewById(R.id.empty).setVisibility(View.GONE);
381             }
382
383             previouslySelectedCell = -1;
384         }
385     }
386
387     private void fadeIn() {
388         mAppWidgetHost.startListening();
389
390         DashboardHelper.getInstance().setDashboardOpen(true);
391
392         layout.setVisibility(View.VISIBLE);
393         layout.animate()
394                 .alpha(1)
395                 .setDuration(context.getResources().getInteger(android.R.integer.config_shortAnimTime))
396                 .setListener(null);
397     }
398
399     private void fadeOut(final boolean sendIntent) {
400         mAppWidgetHost.stopListening();
401
402         DashboardHelper.getInstance().setDashboardOpen(false);
403
404         layout.animate()
405                 .alpha(0)
406                 .setDuration(context.getResources().getInteger(android.R.integer.config_shortAnimTime))
407                 .setListener(new AnimatorListenerAdapter() {
408                     @Override
409                     public void onAnimationEnd(Animator animation) {
410                         layout.setVisibility(View.GONE);
411                         if(sendIntent) LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("com.farmerbb.taskbar.DASHBOARD_DISAPPEARING"));
412                     }
413                 });
414     }
415
416     @TargetApi(Build.VERSION_CODES.M)
417     @Override
418     public void onRecreateHost(Host host) {
419         if(layout != null) {
420             try {
421                 host.removeView(layout);
422             } catch (IllegalArgumentException e) { /* Gracefully fail */ }
423
424             SharedPreferences pref = U.getSharedPreferences(context);
425             if(U.canDrawOverlays(context))
426                 drawDashboard(host);
427             else {
428                 pref.edit().putBoolean("taskbar_active", false).apply();
429
430                 host.terminate();
431             }
432         }
433     }
434
435     @Override
436     public void onDestroyHost(Host host) {
437         if(layout != null)
438             try {
439                 host.removeView(layout);
440             } catch (IllegalArgumentException e) { /* Gracefully fail */ }
441
442         LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context);
443
444         lbm.unregisterReceiver(toggleReceiver);
445         lbm.unregisterReceiver(addWidgetReceiver);
446         lbm.unregisterReceiver(removeWidgetReceiver);
447         lbm.unregisterReceiver(hideReceiver);
448
449         lbm.sendBroadcast(new Intent("com.farmerbb.taskbar.DASHBOARD_DISAPPEARING"));
450     }
451
452     private void cellClick(View view, boolean isActualClick) {
453         Bundle bundle = (Bundle) view.getTag();
454         int cellId = bundle.getInt("cellId");
455         int appWidgetId = bundle.getInt("appWidgetId", -1);
456
457         int currentlySelectedCell = appWidgetId == -1 ? cellId : -1;
458
459         SharedPreferences pref = U.getSharedPreferences(context);
460         boolean shouldShowPlaceholder = pref.getBoolean("dashboard_widget_" + cellId + "_placeholder", false);
461         if(isActualClick && ((appWidgetId == -1 && currentlySelectedCell == previouslySelectedCell) || shouldShowPlaceholder)) {
462             fadeOut(false);
463
464             FrameLayout frameLayout = cells.get(currentlySelectedCell);
465             frameLayout.findViewById(R.id.empty).setVisibility(View.GONE);
466
467             Intent intent = new Intent("com.farmerbb.taskbar.ADD_WIDGET_REQUESTED");
468             intent.putExtra("appWidgetId", APPWIDGET_HOST_ID);
469             intent.putExtra("cellId", cellId);
470             LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
471
472             if(shouldShowPlaceholder) {
473                 String providerName = pref.getString("dashboard_widget_" + cellId + "_provider", "null");
474                 if(!providerName.equals("null")) {
475                     ComponentName componentName = ComponentName.unflattenFromString(providerName);
476
477                     List<AppWidgetProviderInfo> providerInfoList = mAppWidgetManager.getInstalledProvidersForProfile(Process.myUserHandle());
478                     for(AppWidgetProviderInfo info : providerInfoList) {
479                         if(info.provider.equals(componentName)) {
480                             U.showToast(context, context.getString(R.string.widget_restore_toast, info.loadLabel(context.getPackageManager())), Toast.LENGTH_SHORT);
481                             break;
482                         }
483                     }
484                 }
485             }
486
487             previouslySelectedCell = -1;
488         } else {
489             for(int i = 0; i < maxSize; i++) {
490                 FrameLayout frameLayout = cells.get(i);
491                 frameLayout.findViewById(R.id.empty).setVisibility(i == currentlySelectedCell && !shouldShowPlaceholder ? View.VISIBLE : View.GONE);
492             }
493
494             previouslySelectedCell = currentlySelectedCell;
495         }
496     }
497
498     private void cellLongClick(View view) {
499         fadeOut(false);
500
501         Bundle bundle = (Bundle) view.getTag();
502         int cellId = bundle.getInt("cellId");
503
504         Intent intent = new Intent("com.farmerbb.taskbar.REMOVE_WIDGET_REQUESTED");
505         intent.putExtra("cellId", cellId);
506         LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
507     }
508
509     private void addWidget(int appWidgetId, int cellId, boolean shouldSave) {
510         AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
511
512         final DashboardCell cellLayout = cells.get(cellId);
513         final AppWidgetHostView hostView = mAppWidgetHost.createView(context, appWidgetId, appWidgetInfo);
514         hostView.setAppWidget(appWidgetId, appWidgetInfo);
515
516         Bundle bundle = new Bundle();
517         bundle.putInt("cellId", cellId);
518         hostView.setTag(bundle);
519
520         cellLayout.findViewById(R.id.empty).setVisibility(View.GONE);
521         cellLayout.findViewById(R.id.placeholder).setVisibility(View.GONE);
522         cellLayout.setOnLongClickListener(olcl);
523         cellLayout.setOnGenericMotionListener(ogml);
524         cellLayout.setOnInterceptedLongPressListener(listener);
525
526         LinearLayout linearLayout = cellLayout.findViewById(R.id.dashboard);
527         linearLayout.addView(hostView);
528
529         Bundle bundle2 = (Bundle) cellLayout.getTag();
530         bundle2.putInt("appWidgetId", appWidgetId);
531         cellLayout.setTag(bundle2);
532
533         widgets.put(cellId, hostView);
534
535         if(shouldSave) {
536             SharedPreferences pref = U.getSharedPreferences(context);
537             SharedPreferences.Editor editor = pref.edit();
538             editor.putInt("dashboard_widget_" + cellId, appWidgetId);
539             editor.putString("dashboard_widget_" + cellId + "_provider", appWidgetInfo.provider.flattenToString());
540             editor.remove("dashboard_widget_" + cellId + "_placeholder");
541             editor.apply();
542         }
543
544         new Handler().post(() -> {
545             ViewGroup.LayoutParams params = hostView.getLayoutParams();
546             params.width = cellLayout.getWidth();
547             params.height = cellLayout.getHeight();
548             hostView.setLayoutParams(params);
549             hostView.updateAppWidgetSize(null, cellLayout.getWidth(), cellLayout.getHeight(), cellLayout.getWidth(), cellLayout.getHeight());
550         });
551     }
552
553     private void removeWidget(int cellId, boolean tempRemove) {
554         widgets.remove(cellId);
555
556         DashboardCell cellLayout = cells.get(cellId);
557         Bundle bundle = (Bundle) cellLayout.getTag();
558
559         mAppWidgetHost.deleteAppWidgetId(bundle.getInt("appWidgetId"));
560         bundle.remove("appWidgetId");
561
562         LinearLayout linearLayout = cellLayout.findViewById(R.id.dashboard);
563         linearLayout.removeAllViews();
564
565         cellLayout.setTag(bundle);
566         cellLayout.setOnClickListener(cellOcl);
567         cellLayout.setOnHoverListener(cellOhl);
568         cellLayout.setOnLongClickListener(null);
569         cellLayout.setOnGenericMotionListener(null);
570         cellLayout.setOnInterceptedLongPressListener(null);
571
572         SharedPreferences pref = U.getSharedPreferences(context);
573         SharedPreferences.Editor editor = pref.edit();
574         editor.remove("dashboard_widget_" + cellId);
575
576         if(tempRemove) {
577             editor.putBoolean("dashboard_widget_" + cellId + "_placeholder", true);
578             addPlaceholder(cellId);
579         } else
580             editor.remove("dashboard_widget_" + cellId + "_provider");
581
582         editor.apply();
583     }
584
585     private void addPlaceholder(int cellId) {
586         FrameLayout placeholder = cells.get(cellId).findViewById(R.id.placeholder);
587         SharedPreferences pref = U.getSharedPreferences(context);
588         String providerName = pref.getString("dashboard_widget_" + cellId + "_provider", "null");
589
590         if(!providerName.equals("null")) {
591             ImageView imageView = placeholder.findViewById(R.id.placeholder_image);
592             ComponentName componentName = ComponentName.unflattenFromString(providerName);
593
594             List<AppWidgetProviderInfo> providerInfoList = mAppWidgetManager.getInstalledProvidersForProfile(Process.myUserHandle());
595             for(AppWidgetProviderInfo info : providerInfoList) {
596                 if(info.provider.equals(componentName)) {
597                     Drawable drawable = info.loadPreviewImage(context, -1);
598                     if(drawable == null) drawable = info.loadIcon(context, -1);
599
600                     ColorMatrix matrix = new ColorMatrix();
601                     matrix.setSaturation(0);
602
603                     imageView.setImageDrawable(drawable);
604                     imageView.setColorFilter(new ColorMatrixColorFilter(matrix));
605                     break;
606                 }
607             }
608         }
609
610         placeholder.setVisibility(View.VISIBLE);
611     }
612 }