Android Open Source - cpustats Usage Update Service






From Project

Back to project page cpustats.

License

The source code is released under:

Apache License

If you think the Android project cpustats listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package jp.takke.cpustats;
/*www .  j a va2 s  . c om*/
import java.util.ArrayList;

import android.app.AlarmManager;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.preference.PreferenceManager;

class OneCpuInfo {
    long idle = 0;
    long total = 0;
}

public class UsageUpdateService extends Service {

    // ?????ID
    private static final int MY_USAGE_NOTIFICATION_ID = 1;
    private static final int MY_FREQ_NOTIFICATION_ID = 2;

    // ????
    private long mIntervalMs = C.PREF_DEFAULT_UPDATE_INTERVAL_SEC * 1000;
    
    // ??
    private boolean mShowUsageNotification = true;
    private boolean mShowFrequencyNotification = false;
    
    // ??????????
    private boolean mStopResident = false;

    // ????????
    private boolean mSleeping = false;
    
    // CPU ??????????min/max
    private int mMinFreq = -1;
    private String mMinFreqText = "";
    private int mMaxFreq = -1;
    private String mMaxFreqText = "";
    
    // ?????? CPU ???????
    private int mLastCpuClock = -1;
    
    // ?????????????
    private ArrayList<OneCpuInfo> mLastInfo = null;
    
    // ?????????
    private int[] mLastCpuUsages = null;
    
    // ?????????
    private final RemoteCallbackList<IUsageUpdateCallback> mCallbackList = new RemoteCallbackList<IUsageUpdateCallback>();
    
    // ?????????????
    private int mCallbackListSize = 0;
    
    // ?????????
    private final IUsageUpdateService.Stub mBinder = new IUsageUpdateService.Stub() {
                
        public void registerCallback(IUsageUpdateCallback callback) throws RemoteException {
            
            // ????????????
            mCallbackList.register(callback);
            
            mCallbackListSize ++;
        }
        
        public void unregisterCallback(IUsageUpdateCallback callback) throws RemoteException {
            
            // ????????????
            mCallbackList.unregister(callback);
            
            if (mCallbackListSize > 0) {
                mCallbackListSize --;
            }
        }

        public void stopResident() throws RemoteException {
            
            // ???????
            UsageUpdateService.this.stopResident();
        }

        public void startResident() throws RemoteException {

            // ?????????????
            mStopResident = false;
            
            // ????????????? onStart ?????
            UsageUpdateService.this.scheduleNextTime(100);
        }

        /**
         * ?????????
         */
        public void reloadSettings() throws RemoteException {
            
            loadSettings();
            
            // ??????????????????
            if (!mShowUsageNotification) {
                ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).cancel(MY_USAGE_NOTIFICATION_ID);
            }
            if (!mShowFrequencyNotification) {
                ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).cancel(MY_FREQ_NOTIFICATION_ID);
            }
        }
    };

    /**
     * ??????(SCREEN_ON/OFF)???????????
     */
    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
                
                MyLog.d("screen on");
                
                // ????????????????????????
                mSleeping = false;

                // ???? onStart ?????
                // ????????????????????????????????????????????????????????????????????????????????????????????????????????????????
                mNotificationTimeKeep = System.currentTimeMillis() + 30*1000;
                
                UsageUpdateService.this.scheduleNextTime(mIntervalMs);
                
            } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
                
                MyLog.d("screen off");
                
                // ????????
                mSleeping = true;
                
                // ????????
                stopAlarm();
            }
        }
    };

    @Override
    public IBinder onBind(Intent intent) {
        
        if (IUsageUpdateService.class.getName().equals(intent.getAction())) {
            return mBinder;
        }
        
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        
        MyLog.d("UsageUpdateService.onCreate");
        
        // ????????
        loadSettings();
        
        if (mLastInfo == null) {
            mLastInfo = MyUtil.takeCpuUsageSnapshot();
        }
        
        // ????????????????
        getApplicationContext().registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON));
        getApplicationContext().registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
        
        // ????????
        scheduleNextTime(mIntervalMs);
    }
    
    /**
     * ????????
     */
    private void loadSettings() {

        MyLog.i("load settings");
        
        final SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
        
        // ????
        final String updateIntervalSec = pref.getString(C.PREF_KEY_UPDATE_INTERVAL_SEC, ""+C.PREF_DEFAULT_UPDATE_INTERVAL_SEC);
        try {
            mIntervalMs = (int)(Double.parseDouble(updateIntervalSec) * 1000.0);
            MyLog.i(" interval[" + mIntervalMs + "ms]");
        } catch (NumberFormatException e) {
            MyLog.e(e);
        }
        
        // CPU?????
        mShowUsageNotification = pref.getBoolean(C.PREF_KEY_SHOW_USAGE_NOTIFICATION, true);

        // ?????????
        mShowFrequencyNotification = pref.getBoolean(C.PREF_KEY_SHOW_FREQUENCY_NOTIFICATION, false);
    }

    @SuppressWarnings("deprecation")
    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        
        MyLog.d("UsageUpdateService.onStart");
        
        // TODO ???????????????????Task????????????
        execTask();
    }
    
    private void execTask() {
        
        //-------------------------------------------------
        // CPU ??????????????
        //-------------------------------------------------
        final int currentCpuClock = MyUtil.takeCurrentCpuFreq();
        if (mMinFreq < 0) {
            mMinFreq = MyUtil.takeMinCpuFreq();
            mMinFreqText = MyUtil.formatFreq(mMinFreq);
        }
        if (mMaxFreq < 0) {
            mMaxFreq = MyUtil.takeMaxCpuFreq();
            mMaxFreqText = MyUtil.formatFreq(mMaxFreq);
        }
        if (MyLog.debugMode) {
            MyLog.d("CPU:" + currentCpuClock + " [" + mMinFreq + "," + mMaxFreq + "]");
        }
        
        
        //-------------------------------------------------
        // CPU ??????????
        //-------------------------------------------------
        // CPU ?????? snapshot ????
        final ArrayList<OneCpuInfo> currentInfo = MyUtil.takeCpuUsageSnapshot();
        
        // CPU ????????
        final int[] cpuUsages = MyUtil.calcCpuUsages(currentInfo, mLastInfo);
        

        //-------------------------------------------------
        // ????
        //-------------------------------------------------
        // ???????????? CPU ??????????????????
        // ?????????????????????????????????????????????????????????????CPU???%????????????????????????
        boolean updated = false;
        
        if (mLastCpuClock != currentCpuClock) {
            updated = true;
        } else if (mLastCpuUsages == null || cpuUsages == null) {
            updated = true;
        } else if (cpuUsages.length != mLastCpuUsages.length) {
            // ??????????(Galaxy S II???????????????????)
            updated = true;
        } else {
            // ?????????????????????
            final int n = cpuUsages.length;
            for (int i=0; i<n; i++) {
                if (cpuUsages[i] != mLastCpuUsages[i]) {
                    updated = true;
                    break;
                }
            }
        }
        mLastCpuUsages = cpuUsages;
        mLastCpuClock = currentCpuClock;
        
        //-------------------------------------------------
        // ??
        //-------------------------------------------------
        if (!updated) {
            if (MyLog.debugMode) {
                MyLog.d(" skipping caused by no diff.");
            }
        } else {
            // ?????????????
            updateCpuUsageNotifications(cpuUsages, currentCpuClock);
            
            // ??????????????
            if (mCallbackListSize >= 1) {
                final int n = mCallbackList.beginBroadcast();
                
                // ????????????????????????????????
                mCallbackListSize = n;
                
                if (MyLog.debugMode) {
                    MyLog.d(" broadcast:" + n);
                }
                for (int i=0; i<n; i++) {
                    try {
                        mCallbackList.getBroadcastItem(i).updateUsage(cpuUsages, currentCpuClock);
                    } catch (RemoteException e) {
//                      MyLog.e(e);
                    }
                }
                mCallbackList.finishBroadcast();
            }
        }
        
        // ????? snapshot ????
        mLastInfo = currentInfo;
        
        // ?????????
        scheduleNextTime(mIntervalMs);
    }

    
    @Override
    public void onDestroy() {
        
        MyLog.d("UsageUpdateService.onDestroy");
        
        // ????????????????
        getApplicationContext().unregisterReceiver(mReceiver);
        
        // ???????
        ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).cancelAll();

        super.onDestroy();
    }

    // ????[ms]
    private long mNotificationTime = 0;
    
    // ??????????????(???????????????????????????????????????????????????????????????????????????????????????????????????????)[ms]
    protected long mNotificationTimeKeep = 0;
    
    
    /**
     * ???????????????
     */
    @SuppressWarnings("deprecation")
    private void updateCpuUsageNotifications(int[] cpuUsages, int currentCpuClock) {
        
        // N?????????????????????
        final long now = System.currentTimeMillis();
        if (now > mNotificationTime + 3*60*1000 && now > mNotificationTimeKeep) {
            mNotificationTime = now;
        }
        
        final NotificationManager nm = ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE));

        // ?????????????????????????????????
        final Intent intent = new Intent(this, PreviewActivity.class);
        final PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
                PendingIntent.FLAG_CANCEL_CURRENT);
        
        if (cpuUsages != null && mShowUsageNotification) {
            // ???????????????
            final String notificationTitle0 = "CPU Usage";
    
            // Notification.Builder ??? API Level11 ??????????????????????????????
            final int iconId = ResourceUtil.getIconIdForCpuUsage(cpuUsages);
            final Notification notification = new Notification(iconId, notificationTitle0, mNotificationTime);
            
            // ?????????????????????
            notification.flags = Notification.FLAG_ONGOING_EVENT;

            // Lollipop:?????????????????????????
            setPriorityForKeyguardOnLollipop(notification);

            // ???????????
            final StringBuilder sb = new StringBuilder(128);
            // ??????
            if (cpuUsages.length >= 3) {
                sb.append("Cores: ");
                for (int i=1; i<cpuUsages.length; i++) {
                    if (i>=2) {
                        sb.append(" ");
                    }
                    sb.append(cpuUsages[i]).append("%");
                }
            }
            final String notificationContent = sb.toString();
            if (MyLog.debugMode) {
                MyLog.d(" " + notificationContent);
            }
            
            final String notificationTitle = "CPU Usage " + cpuUsages[0] + "%";
            notification.setLatestEventInfo(this, notificationTitle, notificationContent, pendingIntent);

            // ?????????????
            nm.notify(MY_USAGE_NOTIFICATION_ID, notification);
        }
        
        if (currentCpuClock > 0 && mShowFrequencyNotification) {
            // ???????????????
            final String notificationTitle0 = "CPU Frequency";

            // Notification.Builder ??? API Level11 ??????????????????????????????
            final int iconId = ResourceUtil.getIconIdForCpuFreq(currentCpuClock);
            final Notification notification = new Notification(iconId, notificationTitle0, mNotificationTime);
            
            // ?????????????????????
            notification.flags = Notification.FLAG_ONGOING_EVENT;

            // Lollipop:?????????????????????????
            setPriorityForKeyguardOnLollipop(notification);

            // ???????????
            final String notificationTitle = "CPU Frequency " + MyUtil.formatFreq(currentCpuClock);
            final String notificationContent = "Max Freq " + mMaxFreqText + " Min Freq " + mMinFreqText;
            
            notification.setLatestEventInfo(this, notificationTitle, notificationContent, pendingIntent);

            // ?????????????
            nm.notify(MY_FREQ_NOTIFICATION_ID, notification);
        }
    }


    /**
     * ??????????????????????????????
     */
    private void setPriorityForKeyguardOnLollipop(Notification notification) {

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            return;
        }

        final KeyguardManager km = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
        if (km.inKeyguardRestrictedInputMode()) {
            MyLog.d("set notification priority: min");

            // same as: notification.priority = Notification.PRIORITY_MIN;
            try {
                final int Notification_PRIORITY_MIN = -2;   // Notification.PRIORITY_MIN
                notification.getClass().getField("priority").setInt(notification, Notification_PRIORITY_MIN);
            } catch (Exception e) {
                MyLog.e(e);
            }
        }
    }


    /**
     * ?????????????????
     */
    public void scheduleNextTime(long intervalMs) {

        // ??????????????????????????????????????????????
        if (mStopResident) {
            return;
        }
        if (mSleeping) {
            return;
        }

        final long now = System.currentTimeMillis();

        // ????????
        final Intent intent = new Intent(this, this.getClass());
        final PendingIntent alarmSender = PendingIntent.getService(
            this,
            0,
            intent,
            0
        );
        // ?onStart??????????????????????
        
        final AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
        
        am.set(AlarmManager.RTC, now + intervalMs, alarmSender);
        
        MyLog.d(" scheduled[" + intervalMs + "]");
    }
    
    /**
     * ???????
     */
    public void stopResident() {
        
        mStopResident = true;
        
        // ????????
        stopAlarm();
        
        // ???????
        ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).cancelAll();
        
        // ???????
        stopSelf();
    }

    /**
     * ???????????
     */
    private void stopAlarm() {
        
        // ??????????
        final Intent intent = new Intent(this, this.getClass());

        // ???????
        final PendingIntent pendingIntent = PendingIntent.getService(
            this,
            0, // ???????-1???????????????????????????
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT
        );
        
        final AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
        am.cancel(pendingIntent);
            // @see http://creadorgranoeste.blogspot.com/2011/06/alarmmanager.html
    }
}




Java Source Code List

jp.takke.cpustats.BootReceiver.java
jp.takke.cpustats.C.java
jp.takke.cpustats.ConfigActivity.java
jp.takke.cpustats.MyAsyncTask.java
jp.takke.cpustats.MyLog.java
jp.takke.cpustats.MyUtil.java
jp.takke.cpustats.PreviewActivity.java
jp.takke.cpustats.QuadResourceUtil.java
jp.takke.cpustats.QuadResourceUtil.java
jp.takke.cpustats.ResourceUtil.java
jp.takke.cpustats.UsageUpdateService.java