content: /*
   * Copyright (C) 2017 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package com.android.statsd.dogfood;
  
  import android.app.Activity;
  import android.app.PendingIntent;
  import android.app.IntentService;
  import android.app.StatsManager;
  import android.app.StatsManager.StatsUnavailableException;
  import android.content.Context;
  import android.content.Intent;
  import android.content.res.Resources;
  import android.os.Bundle;
  import android.util.Log;
  import android.util.StatsLog;
  import android.view.View;
  import android.widget.TextView;
  import android.widget.Toast;
  import android.os.IStatsManager;
  import android.os.ServiceManager;
  
  import java.io.InputStream;
  
  import static com.android.statsd.dogfood.DisplayProtoUtils.displayLogReport;
  
  public class MainActivity extends Activity {
      private final static String TAG = "StatsdDogfood";
      private final static long CONFIG_ID = 987654321;
  
      final int[] mUids = {11111111, 2222222};
      StatsManager mStatsManager;
      TextView mReportText;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
  
          setContentView(R.layout.activity_main);
  
          findViewById(R.id.app_a_wake_lock_acquire1).setOnClickListener(
                  new View.OnClickListener() {
                      @Override
                      public void onClick(View view) {
                          onWakeLockAcquire(0, "wl_1");
                      }
                  });
  
          findViewById(R.id.app_b_wake_lock_acquire1).setOnClickListener(
                  new View.OnClickListener() {
                      @Override
                      public void onClick(View view) {
                          onWakeLockAcquire(1, "wl_1");
                      }
                  });
  
          findViewById(R.id.app_a_wake_lock_acquire2).setOnClickListener(
                  new View.OnClickListener() {
                      @Override
                      public void onClick(View view) {
                          onWakeLockAcquire(0, "wl_2");
                      }
                  });
  
          findViewById(R.id.app_b_wake_lock_acquire2).setOnClickListener(
                  new View.OnClickListener() {
                      @Override
                      public void onClick(View view) {
                          onWakeLockAcquire(1, "wl_2");
                      }
                  });
  
          findViewById(R.id.app_a_wake_lock_release1).setOnClickListener(
                  new View.OnClickListener() {
                      @Override
                      public void onClick(View view) {
                          onWakeLockRelease(0, "wl_1");
                      }
                  });
  
  
          findViewById(R.id.app_b_wake_lock_release1).setOnClickListener(
                  new View.OnClickListener() {
                      @Override
                      public void onClick(View view) {
                          onWakeLockRelease(1, "wl_1");
                      }
                  });
  
          findViewById(R.id.app_a_wake_lock_release2).setOnClickListener(
                  new View.OnClickListener() {
                      @Override
                      public void onClick(View view) {
                          onWakeLockRelease(0, "wl_2");
                      }
                  });
  
  
          findViewById(R.id.app_b_wake_lock_release2).setOnClickListener(
                  new View.OnClickListener() {
                      @Override
                      public void onClick(View view) {
                          onWakeLockRelease(1, "wl_2");
                      }
                  });
  
  
          findViewById(R.id.plug).setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                  StatsLog.write(StatsLog.PLUGGED_STATE_CHANGED,
                          StatsLog.PLUGGED_STATE_CHANGED__STATE__BATTERY_PLUGGED_AC);
              }
          });
  
          findViewById(R.id.unplug).setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                  StatsLog.write(StatsLog.PLUGGED_STATE_CHANGED,
                          StatsLog.PLUGGED_STATE_CHANGED__STATE__BATTERY_PLUGGED_NONE);
              }
          });
  
          findViewById(R.id.screen_on).setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                  StatsLog.write(StatsLog.SCREEN_STATE_CHANGED,
                          StatsLog.SCREEN_STATE_CHANGED__STATE__DISPLAY_STATE_ON);
              }
          });
  
          findViewById(R.id.screen_off).setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                  StatsLog.write(StatsLog.SCREEN_STATE_CHANGED,
                          StatsLog.SCREEN_STATE_CHANGED__STATE__DISPLAY_STATE_OFF);
              }
          });
  
          findViewById(R.id.custom_start).setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                  StatsLog.logStart(8);
              }
          });
  
          findViewById(R.id.custom_stop).setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                  StatsLog.logStop(8);
              }
          });
  
          mReportText = (TextView) findViewById(R.id.report_text);
  
          findViewById(R.id.dump).setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                  if (!statsdRunning()) {
                      return;
                  }
                  if (mStatsManager != null) {
                      try {
                          byte[] data = mStatsManager.getReports(CONFIG_ID);
                          if (data != null) {
                              displayData(data);
                              return;
                          }
                      } catch (StatsUnavailableException e) {
                          Log.e(TAG, "Failed to get data from statsd", e);
                      }
                      mReportText.setText("Failed!");
                  }
              }
          });
  
          findViewById(R.id.push_config).setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                  try {
                      if (!statsdRunning()) {
                          return;
                      }
                      Resources res = getResources();
                      InputStream inputStream = res.openRawResource(R.raw.statsd_baseline_config);
  
                      byte[] config = new byte[inputStream.available()];
                      inputStream.read(config);
                      if (mStatsManager != null) {
                          try {
                              mStatsManager.addConfig(CONFIG_ID, config);
                              Toast.makeText(
                                      MainActivity.this, "Config pushed", Toast.LENGTH_LONG).show();
                          } catch (StatsUnavailableException | IllegalArgumentException e) {
                              Toast.makeText(MainActivity.this, "Config push FAILED!",
                                      Toast.LENGTH_LONG).show();
                          }
                      }
                  } catch (Exception e) {
                      Toast.makeText(MainActivity.this, "failed to read config", Toast.LENGTH_LONG);
                  }
              }
          });
  
          PendingIntent pi = PendingIntent.getService(this, 0,
                  new Intent(this, ReceiverIntentService.class), PendingIntent.FLAG_UPDATE_CURRENT);
          findViewById(R.id.set_receiver).setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                  try {
                      if (!statsdRunning()) {
                          return;
                      }
                      if (mStatsManager != null) {
                          try {
                              mStatsManager.setFetchReportsOperation(pi, CONFIG_ID);
                              Toast.makeText(MainActivity.this,
                                      "Receiver specified to pending intent", Toast.LENGTH_LONG)
                                      .show();
                          } catch (StatsUnavailableException e) {
                              Toast.makeText(MainActivity.this, "Statsd did not set receiver",
                                      Toast.LENGTH_LONG)
                                      .show();
                          }
                      }
                  } catch (Exception e) {
                      Toast.makeText(MainActivity.this, "failed to set receiver", Toast.LENGTH_LONG);
                  }
              }
          });
          findViewById(R.id.remove_receiver).setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                  try {
                      if (!statsdRunning()) {
                          return;
                      }
                      if (mStatsManager != null) {
                          try {
                              mStatsManager.setFetchReportsOperation(null, CONFIG_ID);
                              Toast.makeText(MainActivity.this, "Receiver remove", Toast.LENGTH_LONG)
                                      .show();
                          } catch (StatsUnavailableException e) {
                              Toast.makeText(MainActivity.this, "Statsd did not remove receiver",
                                      Toast.LENGTH_LONG)
                                      .show();
                          }
                      }
                  } catch (Exception e) {
                      Toast.makeText(
                              MainActivity.this, "failed to remove receiver", Toast.LENGTH_LONG);
                  }
              }
          });
          mStatsManager = (StatsManager) getSystemService("stats");
      }
  
      private boolean statsdRunning() {
          if (IStatsManager.Stub.asInterface(ServiceManager.getService("stats")) == null) {
              Log.d(TAG, "Statsd not running");
              Toast.makeText(MainActivity.this, "Statsd NOT running!", Toast.LENGTH_LONG).show();
              return false;
          }
          return true;
      }
  
      @Override
      public void onNewIntent(Intent intent) {
          Log.d(TAG, "new intent: " + intent.getIntExtra("pkg", 0));
          int pkg = intent.getIntExtra("pkg", 0);
          String name = intent.getStringExtra("name");
          if (intent.hasExtra("acquire")) {
              onWakeLockAcquire(pkg, name);
          } else if (intent.hasExtra("release")) {
              onWakeLockRelease(pkg, name);
          }
      }
  
      private void displayData(byte[] data) {
          com.android.os.StatsLog.ConfigMetricsReportList reports = null;
          boolean good = false;
          if (data != null) {
              try {
                  reports = com.android.os.StatsLog.ConfigMetricsReportList.parseFrom(data);
                  good = true;
              } catch (com.google.protobuf.InvalidProtocolBufferException e) {
                  // display it in the text view.
              }
          }
          int size = data == null ? 0 : data.length;
          StringBuilder sb = new StringBuilder();
          sb.append(good ? "Proto parsing OK!" : "Proto parsing Error!");
          sb.append(" size:").append(size).append("\n");
  
          if (good && reports != null) {
              displayLogReport(sb, reports);
              mReportText.setText(sb.toString());
          }
      }
  
  
      private void onWakeLockAcquire(int id, String name) {
          if (id > 1) {
              Log.d(TAG, "invalid pkg id");
              return;
          }
          int[] uids = new int[]{mUids[id]};
          String[] tags = new String[]{"acquire"};
          StatsLog.write(StatsLog.WAKELOCK_STATE_CHANGED, uids, tags,
                  StatsLog.WAKELOCK_STATE_CHANGED__TYPE__PARTIAL_WAKE_LOCK, name,
                  StatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE);
          StringBuilder sb = new StringBuilder();
          sb.append("StagsLog.write(10, ").append(mUids[id]).append(", ").append(0)
                  .append(", ").append(name).append(", 1);");
          Toast.makeText(this, sb.toString(), Toast.LENGTH_LONG).show();
      }
  
      private void onWakeLockRelease(int id, String name) {
          if (id > 1) {
              Log.d(TAG, "invalid pkg id");
              return;
          }
          int[] uids = new int[]{mUids[id]};
          String[] tags = new String[]{"release"};
          StatsLog.write(StatsLog.WAKELOCK_STATE_CHANGED, uids, tags,
                  StatsLog.WAKELOCK_STATE_CHANGED__TYPE__PARTIAL_WAKE_LOCK, name,
                  StatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE);
          StringBuilder sb = new StringBuilder();
          sb.append("StagsLog.write(10, ").append(mUids[id]).append(", ").append(0)
                  .append(", ").append(name).append(", 0);");
          Toast.makeText(this, sb.toString(), Toast.LENGTH_LONG).show();
      }
  
      public static class ReceiverIntentService extends IntentService {
          public ReceiverIntentService() {
              super("ReceiverIntentService");
          }
  
          /**
           * The IntentService calls this method from the default worker thread with
           * the intent that started the service. When this method returns, IntentService
           * stops the service, as appropriate.
           */
          @Override
          protected void onHandleIntent(Intent intent) {
              Log.i(TAG, "Received notification that we should call getData");
          }
      }
  }
  