Home | History | Annotate | Download | only in policy
      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.statusbar.policy;
     16 
     17 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_NUM_STATUS_ICONS;
     18 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_STATUS_ICONS;
     19 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.STATUS_BAR_ICONS_CHANGED;
     20 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_ACTION;
     21 
     22 import android.content.Context;
     23 import android.metrics.LogMaker;
     24 import android.os.Handler;
     25 import android.os.Looper;
     26 import android.support.annotation.VisibleForTesting;
     27 import android.util.ArraySet;
     28 
     29 import com.android.internal.logging.MetricsLogger;
     30 
     31 import java.util.Arrays;
     32 import java.util.List;
     33 
     34 public class IconLoggerImpl implements IconLogger {
     35 
     36     // Minimum ms between log statements.
     37     // NonFinalForTesting
     38     @VisibleForTesting
     39     protected static long MIN_LOG_INTERVAL = 1000;
     40 
     41     private final Context mContext;
     42     private final Handler mHandler;
     43     private final MetricsLogger mLogger;
     44     private final ArraySet<String> mIcons = new ArraySet<>();
     45     private final List<String> mIconIndex;
     46     private long mLastLog = System.currentTimeMillis();
     47 
     48     public IconLoggerImpl(Context context, Looper bgLooper, MetricsLogger logger) {
     49         mContext = context;
     50         mHandler = new Handler(bgLooper);
     51         mLogger = logger;
     52         String[] icons = mContext.getResources().getStringArray(
     53                 com.android.internal.R.array.config_statusBarIcons);
     54         mIconIndex = Arrays.asList(icons);
     55         doLog();
     56     }
     57 
     58     @Override
     59     public void onIconShown(String tag) {
     60         synchronized (mIcons) {
     61             if (mIcons.contains(tag)) return;
     62             mIcons.add(tag);
     63         }
     64         if (!mHandler.hasCallbacks(mLog)) {
     65             mHandler.postDelayed(mLog, MIN_LOG_INTERVAL);
     66         }
     67     }
     68 
     69     @Override
     70     public void onIconHidden(String tag) {
     71         synchronized (mIcons) {
     72             if (!mIcons.contains(tag)) return;
     73             mIcons.remove(tag);
     74         }
     75         if (!mHandler.hasCallbacks(mLog)) {
     76             mHandler.postDelayed(mLog, MIN_LOG_INTERVAL);
     77         }
     78     }
     79 
     80     private void doLog() {
     81         long time = System.currentTimeMillis();
     82         long timeSinceLastLog = time - mLastLog;
     83         mLastLog = time;
     84 
     85         ArraySet<String> icons;
     86         synchronized (mIcons) {
     87             icons = new ArraySet<>(mIcons);
     88         }
     89         mLogger.write(new LogMaker(STATUS_BAR_ICONS_CHANGED)
     90                 .setType(TYPE_ACTION)
     91                 .setLatency(timeSinceLastLog)
     92                 .addTaggedData(FIELD_NUM_STATUS_ICONS, icons.size())
     93                 .addTaggedData(FIELD_STATUS_ICONS, getBitField(icons)));
     94     }
     95 
     96     private int getBitField(ArraySet<String> icons) {
     97         int iconsVisible = 0;
     98         for (String icon : icons) {
     99             int index = mIconIndex.indexOf(icon);
    100             if (index >= 0) {
    101                 iconsVisible |= (1 << index);
    102             }
    103         }
    104         return iconsVisible;
    105     }
    106 
    107     private final Runnable mLog = this::doLog;
    108 }
    109