private void onStartSurvey()
 {
   if (this.mSurveyBegun) {
     return;
   }
   if (!MPConfig.getInstance(this).getTestMode()) {
     trackSurveyAttempted();
   }
   AlertDialog.Builder localBuilder = new AlertDialog.Builder(this);
   localBuilder.setTitle(R.string.com_mixpanel_android_survey_prompt_dialog_title);
   localBuilder.setMessage(R.string.com_mixpanel_android_survey_prompt_dialog_message);
   localBuilder.setPositiveButton(R.string.com_mixpanel_android_sure, new DialogInterface.OnClickListener()
   {
     public void onClick(DialogInterface paramAnonymousDialogInterface, int paramAnonymousInt)
     {
       SurveyActivity.this.findViewById(R.id.com_mixpanel_android_activity_survey_id).setVisibility(0);
       SurveyActivity.access$402(SurveyActivity.this, true);
       SurveyActivity.this.showQuestion(SurveyActivity.this.mCurrentQuestion);
     }
   });
   localBuilder.setNegativeButton(R.string.com_mixpanel_android_no_thanks, new DialogInterface.OnClickListener()
   {
     public void onClick(DialogInterface paramAnonymousDialogInterface, int paramAnonymousInt)
     {
       SurveyActivity.this.finish();
     }
   });
   localBuilder.setCancelable(false);
   this.mDialog = localBuilder.create();
   this.mDialog.show();
 }
  private void handleNotificationIntent(Context context, Intent intent) {
    final MPConfig config = MPConfig.getInstance(context);
    String resourcePackage = config.getResourcePackageName();
    if (null == resourcePackage) {
      resourcePackage = context.getPackageName();
    }

    final ResourceIds drawableIds = new ResourceReader.Drawables(resourcePackage, context);
    final Context applicationContext = context.getApplicationContext();
    final Notification notification = buildNotification(applicationContext, intent, drawableIds);

    if (null != notification) {
      final NotificationManager notificationManager =
          (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
      notificationManager.notify(0, notification);
    }
  }
  public void testConfiguration() {
    final ApplicationInfo appInfo = new ApplicationInfo();
    appInfo.metaData = new Bundle();
    appInfo.metaData.putInt("com.mixpanel.android.MPConfig.BulkUploadLimit", 1);
    appInfo.metaData.putInt("com.mixpanel.android.MPConfig.FlushInterval", 2);
    appInfo.metaData.putInt("com.mixpanel.android.MPConfig.DataExpiration", 3);
    appInfo.metaData.putBoolean("com.mixpanel.android.MPConfig.DisableFallback", true);
    appInfo.metaData.putBoolean("com.mixpanel.android.MPConfig.AutoShowMixpanelUpdates", false);

    appInfo.metaData.putString("com.mixpanel.android.MPConfig.EventsEndpoint", "EVENTS ENDPOINT");
    appInfo.metaData.putString(
        "com.mixpanel.android.MPConfig.EventsFallbackEndpoint", "EVENTS FALLBACK ENDPOINT");
    appInfo.metaData.putString("com.mixpanel.android.MPConfig.PeopleEndpoint", "PEOPLE ENDPOINT");
    appInfo.metaData.putString(
        "com.mixpanel.android.MPConfig.PeopleFallbackEndpoint", "PEOPLE FALLBACK ENDPOINT");
    appInfo.metaData.putString("com.mixpanel.android.MPConfig.DecideEndpoint", "DECIDE ENDPOINT");
    appInfo.metaData.putString(
        "com.mixpanel.android.MPConfig.DecideFallbackEndpoint", "DECIDE FALLBACK ENDPOINT");

    final PackageManager packageManager =
        new MockPackageManager() {
          @Override
          public ApplicationInfo getApplicationInfo(String packageName, int flags) {
            assertEquals(packageName, "TEST PACKAGE NAME");
            assertTrue((flags & PackageManager.GET_META_DATA) == PackageManager.GET_META_DATA);
            return appInfo;
          }
        };

    final Context context =
        new MockContext() {
          @Override
          public String getPackageName() {
            return "TEST PACKAGE NAME";
          }

          @Override
          public PackageManager getPackageManager() {
            return packageManager;
          }
        };

    final MPConfig testConfig = MPConfig.readConfig(context);
    assertEquals(1, testConfig.getBulkUploadLimit());
    assertEquals(2, testConfig.getFlushInterval());
    assertEquals(3, testConfig.getDataExpiration());
    assertEquals(true, testConfig.getDisableFallback());
    assertEquals(false, testConfig.getAutoShowMixpanelUpdates());
    assertEquals("EVENTS ENDPOINT", testConfig.getEventsEndpoint());
    assertEquals("EVENTS FALLBACK ENDPOINT", testConfig.getEventsFallbackEndpoint());
    assertEquals("PEOPLE ENDPOINT", testConfig.getPeopleEndpoint());
    assertEquals("PEOPLE FALLBACK ENDPOINT", testConfig.getPeopleFallbackEndpoint());
    assertEquals("DECIDE ENDPOINT", testConfig.getDecideEndpoint());
    assertEquals("DECIDE FALLBACK ENDPOINT", testConfig.getDecideFallbackEndpoint());
  }
  public void testMessageQueuing() {
    final BlockingQueue<String> messages = new LinkedBlockingQueue<String>();
    final SynchronizedReference<Boolean> okToDecide = new SynchronizedReference<Boolean>();
    okToDecide.set(false);

    final MPDbAdapter mockAdapter =
        new MPDbAdapter(getContext()) {
          @Override
          public int addJSON(JSONObject message, MPDbAdapter.Table table) {
            try {
              messages.put("TABLE " + table.getName());
              messages.put(message.toString());
            } catch (InterruptedException e) {
              throw new RuntimeException(e);
            }

            return super.addJSON(message, table);
          }
        };
    mockAdapter.cleanupEvents(Long.MAX_VALUE, MPDbAdapter.Table.EVENTS);
    mockAdapter.cleanupEvents(Long.MAX_VALUE, MPDbAdapter.Table.PEOPLE);

    final ServerMessage mockPoster =
        new ServerMessage() {
          @Override
          public byte[] performRequest(String endpointUrl, List<NameValuePair> nameValuePairs) {
            final boolean decideIsOk = okToDecide.get();
            if (null == nameValuePairs) {
              if (decideIsOk) {
                assertEquals(
                    "DECIDE_ENDPOINT?version=1&lib=android&token=Test+Message+Queuing&distinct_id=new+person",
                    endpointUrl);
              } else {
                fail(
                    "User is unidentified, we shouldn't be checking decide. (URL WAS "
                        + endpointUrl
                        + ")");
              }
              return TestUtils.bytes("{}");
            }

            assertEquals(nameValuePairs.get(0).getName(), "data");
            final String decoded = Base64Coder.decodeString(nameValuePairs.get(0).getValue());

            try {
              messages.put("SENT FLUSH " + endpointUrl);
              messages.put(decoded);
            } catch (InterruptedException e) {
              throw new RuntimeException(e);
            }

            return TestUtils.bytes("1\n");
          }
        };

    final MPConfig mockConfig =
        new MPConfig(new Bundle()) {
          @Override
          public int getFlushInterval() {
            return -1;
          }

          @Override
          public int getBulkUploadLimit() {
            return 40;
          }

          @Override
          public String getEventsEndpoint() {
            return "EVENTS_ENDPOINT";
          }

          @Override
          public String getPeopleEndpoint() {
            return "PEOPLE_ENDPOINT";
          }

          @Override
          public String getDecideEndpoint() {
            return "DECIDE_ENDPOINT";
          }
        };

    final AnalyticsMessages listener =
        new AnalyticsMessages(getContext()) {
          @Override
          protected MPDbAdapter makeDbAdapter(Context context) {
            return mockAdapter;
          }

          @Override
          protected MPConfig getConfig(Context context) {
            return mockConfig;
          }

          @Override
          protected ServerMessage getPoster() {
            return mockPoster;
          }
        };

    MixpanelAPI metrics =
        new TestUtils.CleanMixpanelAPI(getContext(), mMockPreferences, "Test Message Queuing") {
          @Override
          protected AnalyticsMessages getAnalyticsMessages() {
            return listener;
          }
        };

    // Test filling up the message queue
    for (int i = 0; i < mockConfig.getBulkUploadLimit() - 1; i++) {
      metrics.track("frequent event", null);
    }

    metrics.track("final event", null);
    String expectedJSONMessage = "<No message actually received>";

    try {
      for (int i = 0; i < mockConfig.getBulkUploadLimit() - 1; i++) {
        String messageTable = messages.poll(1, TimeUnit.SECONDS);
        assertEquals("TABLE " + MPDbAdapter.Table.EVENTS.getName(), messageTable);

        expectedJSONMessage = messages.poll(1, TimeUnit.SECONDS);
        JSONObject message = new JSONObject(expectedJSONMessage);
        assertEquals("frequent event", message.getString("event"));
      }

      String messageTable = messages.poll(1, TimeUnit.SECONDS);
      assertEquals("TABLE " + MPDbAdapter.Table.EVENTS.getName(), messageTable);

      expectedJSONMessage = messages.poll(1, TimeUnit.SECONDS);
      JSONObject message = new JSONObject(expectedJSONMessage);
      assertEquals("final event", message.getString("event"));

      String messageFlush = messages.poll(1, TimeUnit.SECONDS);
      assertEquals("SENT FLUSH EVENTS_ENDPOINT", messageFlush);

      expectedJSONMessage = messages.poll(1, TimeUnit.SECONDS);
      JSONArray bigFlush = new JSONArray(expectedJSONMessage);
      assertEquals(mockConfig.getBulkUploadLimit(), bigFlush.length());

      metrics.track("next wave", null);
      metrics.flush();

      String nextWaveTable = messages.poll(1, TimeUnit.SECONDS);
      assertEquals("TABLE " + MPDbAdapter.Table.EVENTS.getName(), nextWaveTable);

      expectedJSONMessage = messages.poll(1, TimeUnit.SECONDS);
      JSONObject nextWaveMessage = new JSONObject(expectedJSONMessage);
      assertEquals("next wave", nextWaveMessage.getString("event"));

      String manualFlush = messages.poll(1, TimeUnit.SECONDS);
      assertEquals("SENT FLUSH EVENTS_ENDPOINT", manualFlush);

      expectedJSONMessage = messages.poll(1, TimeUnit.SECONDS);
      JSONArray nextWave = new JSONArray(expectedJSONMessage);
      assertEquals(1, nextWave.length());

      JSONObject nextWaveEvent = nextWave.getJSONObject(0);
      assertEquals("next wave", nextWaveEvent.getString("event"));

      okToDecide.set(true);
      metrics.getPeople().identify("new person");
      metrics.getPeople().set("prop", "yup");
      metrics.flush();

      String peopleTable = messages.poll(1, TimeUnit.SECONDS);
      assertEquals("TABLE " + MPDbAdapter.Table.PEOPLE.getName(), peopleTable);

      expectedJSONMessage = messages.poll(1, TimeUnit.SECONDS);
      JSONObject peopleMessage = new JSONObject(expectedJSONMessage);

      assertEquals("new person", peopleMessage.getString("$distinct_id"));
      assertEquals("yup", peopleMessage.getJSONObject("$set").getString("prop"));

      String peopleFlush = messages.poll(1, TimeUnit.SECONDS);
      assertEquals("SENT FLUSH PEOPLE_ENDPOINT", peopleFlush);

      expectedJSONMessage = messages.poll(1, TimeUnit.SECONDS);
      JSONArray peopleSent = new JSONArray(expectedJSONMessage);
      assertEquals(1, peopleSent.length());

    } catch (InterruptedException e) {
      fail("Expected a log message about mixpanel communication but did not recieve it.");
    } catch (JSONException e) {
      fail(
          "Expected a JSON object message and got something silly instead: " + expectedJSONMessage);
    }
  }