@SmallTest
 public void testStressMemoryPropertyConsistency() throws Exception {
   for (int i = 0; i < 100; ++i) {
     SystemProperties.set(KEY, Long.toString(i));
     long ret = SystemProperties.getLong(KEY, -1);
     assertEquals(i, ret);
   }
 }
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.bt_debug_feature);

    TextView tv = (TextView) findViewById(R.id.BTDebugFeaturetxv);
    tv.setText(Html.fromHtml(getString(R.string.BtDebugFeature)));

    mChecked = (CheckBox) findViewById(R.id.BTDebugFeatureCb);
    mChecked.setOnClickListener(this);
    if (0xFFFFFFFFL == SystemProperties.getLong(KEY_DEBUG_FEATURE, 0)) {
      mChecked.setChecked(true);
    } else {
      mChecked.setChecked(false);
    }
  }
 private void updateEnableTracesOptions() {
   long flags = SystemProperties.getLong(Trace.PROPERTY_TRACE_TAG_ENABLEFLAGS, 0);
   String[] values = mEnableTracesPref.getEntryValues();
   int numSet = 0;
   for (int i = Trace.TRACE_FLAGS_START_BIT; i < values.length; i++) {
     boolean set = (flags & (1 << i)) != 0;
     mEnableTracesPref.setValue(i - Trace.TRACE_FLAGS_START_BIT, set);
     if (set) {
       numSet++;
     }
   }
   if (numSet == 0) {
     mEnableTracesPref.setSummary(R.string.enable_traces_summary_none);
   } else if (numSet == values.length) {
     mHaveDebugSettings = true;
     mEnableTracesPref.setSummary(R.string.enable_traces_summary_all);
   } else {
     mHaveDebugSettings = true;
     mEnableTracesPref.setSummary(getString(R.string.enable_traces_summary_num, numSet));
   }
 }
  private void logBootEvents(Context ctx) throws IOException {
    final DropBoxManager db = (DropBoxManager) ctx.getSystemService(Context.DROPBOX_SERVICE);
    final SharedPreferences prefs = ctx.getSharedPreferences("log_files", Context.MODE_PRIVATE);
    final String headers =
        new StringBuilder(512)
            .append("Build: ")
            .append(Build.FINGERPRINT)
            .append("\n")
            .append("Hardware: ")
            .append(Build.BOARD)
            .append("\n")
            .append("Bootloader: ")
            .append(Build.BOOTLOADER)
            .append("\n")
            .append("Radio: ")
            .append(Build.RADIO)
            .append("\n")
            .append("Kernel: ")
            .append(FileUtils.readTextFile(new File("/proc/version"), 1024, "...\n"))
            .append("\n")
            .toString();

    String recovery = RecoverySystem.handleAftermath();
    if (recovery != null && db != null) {
      db.addText("SYSTEM_RECOVERY_LOG", headers + recovery);
    }

    if (SystemProperties.getLong("ro.runtime.firstboot", 0) == 0) {
      String now = Long.toString(System.currentTimeMillis());
      SystemProperties.set("ro.runtime.firstboot", now);
      if (db != null) db.addText("SYSTEM_BOOT", headers);

      // Negative sizes mean to take the *tail* of the file (see FileUtils.readTextFile())
      addFileToDropBox(db, prefs, headers, "/proc/last_kmsg", -LOG_SIZE, "SYSTEM_LAST_KMSG");
      addFileToDropBox(db, prefs, headers, "/cache/recovery/log", -LOG_SIZE, "SYSTEM_RECOVERY_LOG");
      addFileToDropBox(
          db, prefs, headers, "/data/dontpanic/apanic_console", -LOG_SIZE, "APANIC_CONSOLE");
      addFileToDropBox(
          db, prefs, headers, "/data/dontpanic/apanic_threads", -LOG_SIZE, "APANIC_THREADS");
    } else {
      if (db != null) db.addText("SYSTEM_RESTART", headers);
    }

    // Scan existing tombstones (in case any new ones appeared)
    File[] tombstoneFiles = TOMBSTONE_DIR.listFiles();
    for (int i = 0; tombstoneFiles != null && i < tombstoneFiles.length; i++) {
      addFileToDropBox(
          db, prefs, headers, tombstoneFiles[i].getPath(), LOG_SIZE, "SYSTEM_TOMBSTONE");
    }

    // Start watching for new tombstone files; will record them as they occur.
    // This gets registered with the singleton file observer thread.
    sTombstoneObserver =
        new FileObserver(TOMBSTONE_DIR.getPath(), FileObserver.CLOSE_WRITE) {
          @Override
          public void onEvent(int event, String path) {
            try {
              String filename = new File(TOMBSTONE_DIR, path).getPath();
              addFileToDropBox(db, prefs, headers, filename, LOG_SIZE, "SYSTEM_TOMBSTONE");
            } catch (IOException e) {
              Slog.e(TAG, "Can't log tombstone", e);
            }
          }
        };

    sTombstoneObserver.startWatching();
  }
/**
 * Sensor manager implementation that communicates with the built-in system sensors.
 *
 * @hide
 */
public class SystemSensorManager extends SensorManager {
  private static final int SENSOR_DISABLE = -1;
  private static final long SENSOR_LOOPMINMS =
      SystemProperties.getLong(
          "sensor.loop.minms",
          0); // minimal duration of a sensor loop => sleep to prevent notification storm if faster
              // than that.
  private static final float MAGNITUDE_THRESHOLD =
      ((float) SystemProperties.getLong("sensor.magnitude.threshold", 0)) / 1000.0f;

  private static boolean sSensorModuleInitialized = false;
  private static ArrayList<Sensor> sFullSensorsList = new ArrayList<Sensor>();
  /* The thread and the sensor list are global to the process
   * but the actual thread is spawned on demand */
  private static SensorThread sSensorThread;
  private static int sQueue;

  // Used within this module from outside SensorManager, don't make private
  static SparseArray<Sensor> sHandleToSensor = new SparseArray<Sensor>();
  static final ArrayList<ListenerDelegate> sListeners = new ArrayList<ListenerDelegate>();

  // Common pool of sensor events.
  static SensorEventPool sPool;

  // Looper associated with the context in which this instance was created.
  final Looper mMainLooper;

  /*-----------------------------------------------------------------------*/

  private static class SensorThread {

    Thread mThread;
    boolean mSensorsReady;

    SensorThread() {}

    @Override
    protected void finalize() {}

    // must be called with sListeners lock
    boolean startLocked() {
      try {
        if (mThread == null) {
          mSensorsReady = false;
          SensorThreadRunnable runnable = new SensorThreadRunnable();
          Thread thread = new Thread(runnable, SensorThread.class.getName());
          thread.start();
          synchronized (runnable) {
            while (mSensorsReady == false) {
              runnable.wait();
            }
          }
          mThread = thread;
        }
      } catch (InterruptedException e) {
      }
      return mThread == null ? false : true;
    }

    private class SensorThreadRunnable implements Runnable {
      SensorThreadRunnable() {}

      private boolean open() {
        // NOTE: this cannot synchronize on sListeners, since
        // it's held in the main thread at least until we
        // return from here.
        sQueue = sensors_create_queue();
        return true;
      }

      public void run() {
        // Log.d(TAG, "entering main sensor thread");
        final float[] values = new float[3];
        final int[] status = new int[1];
        final long timestamp[] = new long[1];
        Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_DISPLAY);

        if (!open()) {
          return;
        }

        synchronized (this) {
          // we've open the driver, we're ready to open the sensors
          mSensorsReady = true;
          this.notify();
        }

        while (true) {
          // wait for an event
          final int sensor = sensors_data_poll(sQueue, values, status, timestamp);
          long lastLoopMS = System.currentTimeMillis();
          long timeToSleep = SENSOR_LOOPMINMS;

          int accuracy = status[0];
          synchronized (sListeners) {
            if (sensor == -1 || sListeners.isEmpty()) {
              // we lost the connection to the event stream. this happens
              // when the last listener is removed or if there is an error
              if (sensor == -1 && !sListeners.isEmpty()) {
                // log a warning in case of abnormal termination
                Log.e(TAG, "_sensors_data_poll() failed, we bail out: sensors=" + sensor);
              }
              // we have no more listeners or polling failed, terminate the thread
              sensors_destroy_queue(sQueue);
              sQueue = 0;
              mThread = null;
              break;
            }
            final Sensor sensorObject = sHandleToSensor.get(sensor);

            if (sensorObject != null) {
              final float mag =
                  FloatMath.sqrt(
                      values[0] * values[0] + values[1] * values[1] + values[2] * values[2]);
              if (Math.abs(mag - SensorManager.STANDARD_GRAVITY) > MAGNITUDE_THRESHOLD) {
                // report the sensor event to all listeners that
                // care about it.
                final int size = sListeners.size();
                for (int i = 0; i < size; i++) {
                  ListenerDelegate listener = sListeners.get(i);
                  if (listener.hasSensor(sensorObject)) {
                    // this is asynchronous (okay to call
                    // with sListeners lock held).
                    listener.onSensorChangedLocked(sensorObject, values, timestamp, accuracy);
                  }
                }
              }
            }
          }

          timeToSleep = SENSOR_LOOPMINMS - (System.currentTimeMillis() - lastLoopMS);
          lastLoopMS = System.currentTimeMillis();
          try {
            if (timeToSleep > 0) Thread.sleep(timeToSleep);
          } catch (InterruptedException e) {;
          }
        }
        // Log.d(TAG, "exiting main sensor thread");
      }
    }
  }

  /*-----------------------------------------------------------------------*/

  private class ListenerDelegate {
    private final SensorEventListener mSensorEventListener;
    private final ArrayList<Sensor> mSensorList = new ArrayList<Sensor>();
    private final Handler mHandler;
    public SparseBooleanArray mSensors = new SparseBooleanArray();
    public SparseBooleanArray mFirstEvent = new SparseBooleanArray();
    public SparseIntArray mSensorAccuracies = new SparseIntArray();

    ListenerDelegate(SensorEventListener listener, Sensor sensor, Handler handler) {
      mSensorEventListener = listener;
      Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
      // currently we create one Handler instance per listener, but we could
      // have one per looper (we'd need to pass the ListenerDelegate
      // instance to handleMessage and keep track of them separately).
      mHandler =
          new Handler(looper) {
            @Override
            public void handleMessage(Message msg) {
              final SensorEvent t = (SensorEvent) msg.obj;
              final int handle = t.sensor.getHandle();

              switch (t.sensor.getType()) {
                  // Only report accuracy for sensors that support it.
                case Sensor.TYPE_MAGNETIC_FIELD:
                case Sensor.TYPE_ORIENTATION:
                  // call onAccuracyChanged() only if the value changes
                  final int accuracy = mSensorAccuracies.get(handle);
                  if ((t.accuracy >= 0) && (accuracy != t.accuracy)) {
                    mSensorAccuracies.put(handle, t.accuracy);
                    mSensorEventListener.onAccuracyChanged(t.sensor, t.accuracy);
                  }
                  break;
                default:
                  // For other sensors, just report the accuracy once
                  if (mFirstEvent.get(handle) == false) {
                    mFirstEvent.put(handle, true);
                    mSensorEventListener.onAccuracyChanged(t.sensor, SENSOR_STATUS_ACCURACY_HIGH);
                  }
                  break;
              }

              mSensorEventListener.onSensorChanged(t);
              sPool.returnToPool(t);
            }
          };
      addSensor(sensor);
    }

    Object getListener() {
      return mSensorEventListener;
    }

    void addSensor(Sensor sensor) {
      mSensors.put(sensor.getHandle(), true);
      mSensorList.add(sensor);
    }

    int removeSensor(Sensor sensor) {
      mSensors.delete(sensor.getHandle());
      mSensorList.remove(sensor);
      return mSensors.size();
    }

    boolean hasSensor(Sensor sensor) {
      return mSensors.get(sensor.getHandle());
    }

    List<Sensor> getSensors() {
      return mSensorList;
    }

    void onSensorChangedLocked(Sensor sensor, float[] values, long[] timestamp, int accuracy) {
      SensorEvent t = sPool.getFromPool();
      final float[] v = t.values;
      v[0] = values[0];
      v[1] = values[1];
      v[2] = values[2];
      t.timestamp = timestamp[0];
      t.accuracy = accuracy;
      t.sensor = sensor;
      Message msg = Message.obtain();
      msg.what = 0;
      msg.obj = t;
      msg.setAsynchronous(true);
      mHandler.sendMessage(msg);
    }
  }

  /** {@hide} */
  public SystemSensorManager(Looper mainLooper) {
    mMainLooper = mainLooper;

    synchronized (sListeners) {
      if (!sSensorModuleInitialized) {
        sSensorModuleInitialized = true;

        nativeClassInit();

        // initialize the sensor list
        sensors_module_init();
        final ArrayList<Sensor> fullList = sFullSensorsList;
        int i = 0;
        do {
          Sensor sensor = new Sensor();
          i = sensors_module_get_next_sensor(sensor, i);

          if (i >= 0) {
            // Log.d(TAG, "found sensor: " + sensor.getName() +
            //        ", handle=" + sensor.getHandle());
            fullList.add(sensor);
            sHandleToSensor.append(sensor.getHandle(), sensor);
          }
        } while (i > 0);

        sPool = new SensorEventPool(sFullSensorsList.size() * 2);
        sSensorThread = new SensorThread();
      }
    }
  }

  /** @hide */
  @Override
  protected List<Sensor> getFullSensorList() {
    return sFullSensorsList;
  }

  private boolean enableSensorLocked(Sensor sensor, int delay) {
    boolean result = false;
    for (ListenerDelegate i : sListeners) {
      if (i.hasSensor(sensor)) {
        String name = sensor.getName();
        int handle = sensor.getHandle();
        result = sensors_enable_sensor(sQueue, name, handle, delay);
        break;
      }
    }
    return result;
  }

  private boolean disableSensorLocked(Sensor sensor) {
    for (ListenerDelegate i : sListeners) {
      if (i.hasSensor(sensor)) {
        // not an error, it's just that this sensor is still in use
        return true;
      }
    }
    String name = sensor.getName();
    int handle = sensor.getHandle();
    return sensors_enable_sensor(sQueue, name, handle, SENSOR_DISABLE);
  }

  /** @hide */
  @Override
  protected boolean registerListenerImpl(
      SensorEventListener listener, Sensor sensor, int delay, Handler handler) {
    boolean result = true;
    synchronized (sListeners) {
      // look for this listener in our list
      ListenerDelegate l = null;
      for (ListenerDelegate i : sListeners) {
        if (i.getListener() == listener) {
          l = i;
          break;
        }
      }

      // if we don't find it, add it to the list
      if (l == null) {
        l = new ListenerDelegate(listener, sensor, handler);
        sListeners.add(l);
        // if the list is not empty, start our main thread
        if (!sListeners.isEmpty()) {
          if (sSensorThread.startLocked()) {
            if (!enableSensorLocked(sensor, delay)) {
              // oops. there was an error
              sListeners.remove(l);
              result = false;
            }
          } else {
            // there was an error, remove the listener
            sListeners.remove(l);
            result = false;
          }
        } else {
          // weird, we couldn't add the listener
          result = false;
        }
      } else if (!l.hasSensor(sensor)) {
        l.addSensor(sensor);
        if (!enableSensorLocked(sensor, delay)) {
          // oops. there was an error
          l.removeSensor(sensor);
          result = false;
        }
      }
    }

    return result;
  }

  /** @hide */
  @Override
  protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) {
    synchronized (sListeners) {
      final int size = sListeners.size();
      for (int i = 0; i < size; i++) {
        ListenerDelegate l = sListeners.get(i);
        if (l.getListener() == listener) {
          if (sensor == null) {
            sListeners.remove(i);
            // disable all sensors for this listener
            for (Sensor s : l.getSensors()) {
              disableSensorLocked(s);
            }
          } else if (l.removeSensor(sensor) == 0) {
            // if we have no more sensors enabled on this listener,
            // take it off the list.
            sListeners.remove(i);
            disableSensorLocked(sensor);
          }
          break;
        }
      }
    }
  }

  private static native void nativeClassInit();

  private static native int sensors_module_init();

  private static native int sensors_module_get_next_sensor(Sensor sensor, int next);

  // Used within this module from outside SensorManager, don't make private
  static native int sensors_create_queue();

  static native void sensors_destroy_queue(int queue);

  static native boolean sensors_enable_sensor(int queue, String name, int sensor, int enable);

  static native int sensors_data_poll(int queue, float[] values, int[] status, long[] timestamp);
}
  private void logBootEvents(Context ctx) throws IOException {
    final DropBoxManager db = (DropBoxManager) ctx.getSystemService(Context.DROPBOX_SERVICE);
    final SharedPreferences prefs = ctx.getSharedPreferences("log_files", Context.MODE_PRIVATE);
    final String headers =
        new StringBuilder(512)
            .append("Build: ")
            .append(Build.FINGERPRINT)
            .append("\n")
            .append("Hardware: ")
            .append(Build.BOARD)
            .append("\n")
            .append("Revision: ")
            .append(SystemProperties.get("ro.revision", ""))
            .append("\n")
            .append("Bootloader: ")
            .append(Build.BOOTLOADER)
            .append("\n")
            .append("Radio: ")
            .append(Build.RADIO)
            .append("\n")
            .append("Kernel: ")
            .append(FileUtils.readTextFile(new File("/proc/version"), 1024, "...\n"))
            .append("\n")
            .toString();
    final String bootReason = SystemProperties.get("ro.boot.bootreason", null);

    String recovery = RecoverySystem.handleAftermath();
    if (recovery != null && db != null) {
      db.addText("SYSTEM_RECOVERY_LOG", headers + recovery);
    }

    String lastKmsgFooter = "";
    if (bootReason != null) {
      lastKmsgFooter =
          new StringBuilder(512)
              .append("\n")
              .append("Boot info:\n")
              .append("Last boot reason: ")
              .append(bootReason)
              .append("\n")
              .toString();
    }

    if (SystemProperties.getLong("ro.runtime.firstboot", 0) == 0) {
      if ("encrypted".equals(SystemProperties.get("ro.crypto.state"))
          && "trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))) {
        // Encrypted, first boot to get PIN/pattern/password so data is tmpfs
        // Don't set ro.runtime.firstboot so that we will do this again
        // when data is properly mounted
      } else {
        String now = Long.toString(System.currentTimeMillis());
        SystemProperties.set("ro.runtime.firstboot", now);
      }
      if (db != null) db.addText("SYSTEM_BOOT", headers);

      // Negative sizes mean to take the *tail* of the file (see FileUtils.readTextFile())
      addFileWithFootersToDropBox(
          db, prefs, headers, lastKmsgFooter, "/proc/last_kmsg", -LOG_SIZE, "SYSTEM_LAST_KMSG");
      addFileWithFootersToDropBox(
          db,
          prefs,
          headers,
          lastKmsgFooter,
          "/sys/fs/pstore/console-ramoops",
          -LOG_SIZE,
          "SYSTEM_LAST_KMSG");
      addFileToDropBox(db, prefs, headers, "/cache/recovery/log", -LOG_SIZE, "SYSTEM_RECOVERY_LOG");
      addFileToDropBox(
          db, prefs, headers, "/cache/recovery/last_kmsg", -LOG_SIZE, "SYSTEM_RECOVERY_KMSG");
      addFileToDropBox(
          db, prefs, headers, "/data/dontpanic/apanic_console", -LOG_SIZE, "APANIC_CONSOLE");
      addFileToDropBox(
          db, prefs, headers, "/data/dontpanic/apanic_threads", -LOG_SIZE, "APANIC_THREADS");
      addAuditErrorsToDropBox(db, prefs, headers, -LOG_SIZE, "SYSTEM_AUDIT");
      addFsckErrorsToDropBox(db, prefs, headers, -LOG_SIZE, "SYSTEM_FSCK");
    } else {
      if (db != null) db.addText("SYSTEM_RESTART", headers);
    }

    // Scan existing tombstones (in case any new ones appeared)
    File[] tombstoneFiles = TOMBSTONE_DIR.listFiles();
    for (int i = 0; tombstoneFiles != null && i < tombstoneFiles.length; i++) {
      if (tombstoneFiles[i].isFile()) {
        addFileToDropBox(
            db, prefs, headers, tombstoneFiles[i].getPath(), LOG_SIZE, "SYSTEM_TOMBSTONE");
      }
    }

    // Start watching for new tombstone files; will record them as they occur.
    // This gets registered with the singleton file observer thread.
    sTombstoneObserver =
        new FileObserver(TOMBSTONE_DIR.getPath(), FileObserver.CLOSE_WRITE) {
          @Override
          public void onEvent(int event, String path) {
            try {
              File file = new File(TOMBSTONE_DIR, path);
              if (file.isFile()) {
                addFileToDropBox(db, prefs, headers, file.getPath(), LOG_SIZE, "SYSTEM_TOMBSTONE");
              }
            } catch (IOException e) {
              Slog.e(TAG, "Can't log tombstone", e);
            }
          }
        };

    sTombstoneObserver.startWatching();
  }