Home | History | Annotate | Download | only in util
      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      */
     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 
     54         public DisableStateTracker(int disableMask, int disable2Mask) {
     55             mMask1 = disableMask;
     56             mMask2 = disable2Mask;
     57         }
     58 
     59         @Override
     60         public void onViewAttachedToWindow(View v) {
     61             mView = v;
     62             SysUiServiceProvider.getComponent(v.getContext(), CommandQueue.class)
     63                     .addCallback(this);
     64         }
     65 
     66         @Override
     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
     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 */
     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      */
    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