1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 15 package com.android.systemui.util; 16 17 import android.Manifest; 18 import android.content.Intent; 19 import android.content.pm.PackageManager; 20 import android.view.View; 21 22 import com.android.systemui.SysUiServiceProvider; 23 import com.android.systemui.statusbar.CommandQueue; 24 25 import java.util.List; 26 import java.util.function.Consumer; 27 28 public class Utils { 29 30 /** 31 * Allows lambda iteration over a list. It is done in reverse order so it is safe 32 * to add or remove items during the iteration. Skips over null items. 33 */ safeForeach(List<T> list, Consumer<T> c)34 public static <T> void safeForeach(List<T> list, Consumer<T> c) { 35 for (int i = list.size() - 1; i >= 0; i--) { 36 T item = list.get(i); 37 if (item != null) { 38 c.accept(item); 39 } 40 } 41 } 42 43 /** 44 * Sets the visibility of an UI element according to the DISABLE_* flags in 45 * {@link android.app.StatusBarManager}. 46 */ 47 public static class DisableStateTracker implements CommandQueue.Callbacks, 48 View.OnAttachStateChangeListener { 49 private final int mMask1; 50 private final int mMask2; 51 private View mView; 52 private boolean mDisabled; 53 DisableStateTracker(int disableMask, int disable2Mask)54 public DisableStateTracker(int disableMask, int disable2Mask) { 55 mMask1 = disableMask; 56 mMask2 = disable2Mask; 57 } 58 59 @Override onViewAttachedToWindow(View v)60 public void onViewAttachedToWindow(View v) { 61 mView = v; 62 SysUiServiceProvider.getComponent(v.getContext(), CommandQueue.class) 63 .addCallback(this); 64 } 65 66 @Override onViewDetachedFromWindow(View v)67 public void onViewDetachedFromWindow(View v) { 68 SysUiServiceProvider.getComponent(mView.getContext(), CommandQueue.class) 69 .removeCallback(this); 70 mView = null; 71 } 72 73 /** 74 * Sets visibility of this {@link View} given the states passed from 75 * {@link com.android.systemui.statusbar.CommandQueue.Callbacks#disable(int, int, int)}. 76 */ 77 @Override disable(int displayId, int state1, int state2, boolean animate)78 public void disable(int displayId, int state1, int state2, boolean animate) { 79 if (displayId != mView.getDisplay().getDisplayId()) { 80 return; 81 } 82 final boolean disabled = ((state1 & mMask1) != 0) || ((state2 & mMask2) != 0); 83 if (disabled == mDisabled) return; 84 mDisabled = disabled; 85 mView.setVisibility(disabled ? View.GONE : View.VISIBLE); 86 } 87 88 /** @return {@code true} if and only if this {@link View} is currently disabled */ isDisabled()89 public boolean isDisabled() { 90 return mDisabled; 91 } 92 } 93 94 95 /** 96 * Returns {@code true} iff the package {@code packageName} is a headless remote display 97 * provider, i.e, that the package holds the privileged {@code REMOTE_DISPLAY_PROVIDER} 98 * permission and that it doesn't host a launcher icon. 99 */ isHeadlessRemoteDisplayProvider(PackageManager pm, String packageName)100 public static boolean isHeadlessRemoteDisplayProvider(PackageManager pm, String packageName) { 101 if (pm.checkPermission(Manifest.permission.REMOTE_DISPLAY_PROVIDER, packageName) 102 != PackageManager.PERMISSION_GRANTED) { 103 return false; 104 } 105 106 Intent homeIntent = new Intent(Intent.ACTION_MAIN); 107 homeIntent.addCategory(Intent.CATEGORY_LAUNCHER); 108 homeIntent.setPackage(packageName); 109 110 return pm.queryIntentActivities(homeIntent, 0).isEmpty(); 111 } 112 113 } 114