java - Proper use cases for Android UserManager.isUserAGoat()?


I was looking at the new APIs introduced in Android 4.2. While looking at the UserManager class I came across the following method:

 public boolean isUserAGoat()

Used to determine whether the user making this call is subject to teleportations.

Returns whether the user making this call is a goat.

How and when should this be used?



Answers


From their source, the method used to return false until it was changed in API 21.

/**
 * Used to determine whether the user making this call is subject to
 * teleportations.
 * @return whether the user making this call is a goat 
 */
public boolean isUserAGoat() {
    return false;
}

It looks like the method has no real use for us as developers. Someone has previously stated that it might be an Easter egg.

In API 21 the implementation was changed to check if there is an installed app with the package com.coffeestainstudios.goatsimulator

/**
 * Used to determine whether the user making this call is subject to
 * teleportations.
 *
 * <p>As of {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method can
 * now automatically identify goats using advanced goat recognition technology.</p>
 *
 * @return Returns true if the user making this call is a goat.
 */
public boolean isUserAGoat() {
    return mContext.getPackageManager()
            .isPackageAvailable("com.coffeestainstudios.goatsimulator");
}

Here is the source link




I don't know if this was "the" official use case but the following produces a warning in Java (that can further produce compile errors if mixed with return statements, leading to unreachable code):

while (1 == 2) { // note "if" is treate differently
    System.out.println("Unreachable code");
}

However this is legal:

while (isUserAGoat()) {
    System.out.println("Unreachable but determined at runtime, not at compile time");
}

So I often find myself writing a silly utility method for the quickest way to dummy out a code block, then in completing debugging find all calls to it, so provided the implementation doesn't change this can be used for that.

JLS points out if (false) does not trigger "unreachable code" for the specific reason that this would break support for debug flags i.e. basically this use case (h/t @auselen). (static final boolean DEBUG = false; for instance). I replaced while for if, producing a more obscure use case. I believe you can trip up your IDE, like Eclipse, with this behavior, but this edit is 4 years into the future and I don't have an Eclipse environment to play with.




This appears to be an inside joke at Google. It's also featured in the Google Chrome task manager. It has no purpose, other than some engineers finding it amusing. Which is a purpose by itself, if you will.

  1. In Chrome, open the Task Manager with Shift+Esc.
  2. Right click to add the Goats Teleported column.
  3. Wonder.

There is even a huge Chromium bug report about too many teleported goats.

The following Chromium source code snippet is stolen from the HN comments.

int TaskManagerModel::GetGoatsTeleported(int index) const {
  int seed = goat_salt_ * (index + 1);
  return (seed >> 16) & 255;
}



EProgrammerNotFound exception in Delphi?

It is just the result of a long day and we had gotten a little giddy. For many, many years (ever since I'd been on the team), we'd always joked about replacing some error message in the compiler for one of the most common errors with a similar message. Internally we've always joked and poked fun at different things and people (mostly on the team itself). If you don't have a sense of humor, you're destined to an early grave.

It was a simple conversation;

"Oh, you should have raised the EProgrammerNotFound exception in that function."
"LOL! We should add that exception and see who notices."
"I wonder how much speculation there will be about why it is there?"

So, I guess all I can say is, "You've all played right into our hands ;-)... Buwahahaha! pwned!"




It is used in conjunction with the "fix-inline" technology which requires that the programmer has to be linked into the exe file ;-)




It was introduced in Delphi 2009, still present in Delphi 2010, and recently got some more attention on the internet.

I think it is an easter egg, similar to "EBCAK" (Error Between Chair and Keyboard), and the skipping of Delphi version number 13.

EProgrammerNotFound

  • is declared in the Win32 branch of the SysUtils unit, but not used anywhere in the RTL or VCL
  • is not present in Delphi Prism
  • was introduced in Delphi 2009, so not present in VCL.NET
  • has currently (version 3.5) nothing similar in the .NET framework (not sure why, these guys do have humour)

I don't think EProgrammerNotFound is actually meant to be used at all, but since it is there, people will jokingly use it (similar like putting a stray "const False = True; True = not False;" in someone elses sourcecode).

--jeroen




Strange function in ActivityManager: isUserAMonkey. What does this mean, what is its use?

This method is for checking whether the current user is a test user by some automatic testing.







ExceptionWithContext gets thrown when trying to build an Android app with Ant

I had the same exception while compiling a project for release. My code was:

if (BuildConfig.DEBUG) {
    myView.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // Do something
        }
    });
}

Because BuildConfig.DEBUG is a constant with value false, the code in the block is recognized as dead code and removed when optimized.

The CfTranslator (Classfile Translator) wants to create a separate file for the anonymous class inside the block (SomeClass$1.class), but since it is optimized away an error will occur. I took the anonymous class outside the curly braces the problem was solved:

View.OnClickListener lClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // Do something
    }
};

if (BuildConfig.DEBUG) {
    myView.setOnClickListener(lClickListener);
}

Update: Another way to solve this (described by @Ewoks in his answer below) is:

public boolean isInDeveloperMode() {
    return BuildConfig.DEBUG;
}

...

if (isInDeveloperMode()) {
    myView.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // Do something
        }
    });
}



After months of fighting this exact problem, I have finally found a solution that works for me. It might not be your case. Make sure, that none of the classes you are referring to (Maybe Settings? Maybe AndroidUncaughtExceptionHandler?) is private. The Gradle is not able to handle it and cannot find the method within the class. Just change it to public (or just delete the flag to keep it default, if the class is nested), and you should be good to go.




Other solution than proposed by @Albert-Jan would be to "wrap" that constant in a method. Something like

public boolean isInDeveloperMode(){ return BuildConfig.DEBUG; }

in which case it will not be "resolved" as constant by gradle and there will be no problem during build time.

Probably the most famous "exploit" of this approach would be isUserAGoat() method from UserManager class in Android SDK. There is very popular discussion here about possible uses of this method.. Enjoy ;)

Hopefully this will be useful for somebody with similar issues