Merge "Implement issue #22403908: Enable assistant to refuse context sharing" into mnc-dev

This commit is contained in:
Dianne Hackborn
2015-07-15 23:31:09 +00:00
committed by Android (Google) Code Review
10 changed files with 224 additions and 33 deletions

View File

@@ -28785,11 +28785,13 @@ package android.service.voice {
public class VoiceInteractionService extends android.app.Service { public class VoiceInteractionService extends android.app.Service {
ctor public VoiceInteractionService(); ctor public VoiceInteractionService();
method public final android.service.voice.AlwaysOnHotwordDetector createAlwaysOnHotwordDetector(java.lang.String, java.util.Locale, android.service.voice.AlwaysOnHotwordDetector.Callback); method public final android.service.voice.AlwaysOnHotwordDetector createAlwaysOnHotwordDetector(java.lang.String, java.util.Locale, android.service.voice.AlwaysOnHotwordDetector.Callback);
method public int getDisabledShowContext();
method public static boolean isActiveService(android.content.Context, android.content.ComponentName); method public static boolean isActiveService(android.content.Context, android.content.ComponentName);
method public android.os.IBinder onBind(android.content.Intent); method public android.os.IBinder onBind(android.content.Intent);
method public void onLaunchVoiceAssistFromKeyguard(); method public void onLaunchVoiceAssistFromKeyguard();
method public void onReady(); method public void onReady();
method public void onShutdown(); method public void onShutdown();
method public void setDisabledShowContext(int);
method public void showSession(android.os.Bundle, int); method public void showSession(android.os.Bundle, int);
field public static final java.lang.String SERVICE_INTERFACE = "android.service.voice.VoiceInteractionService"; field public static final java.lang.String SERVICE_INTERFACE = "android.service.voice.VoiceInteractionService";
field public static final java.lang.String SERVICE_META_DATA = "android.voice_interaction"; field public static final java.lang.String SERVICE_META_DATA = "android.voice_interaction";
@@ -28801,6 +28803,7 @@ package android.service.voice {
method public void closeSystemDialogs(); method public void closeSystemDialogs();
method public void finish(); method public void finish();
method public android.content.Context getContext(); method public android.content.Context getContext();
method public int getDisabledShowContext();
method public android.view.LayoutInflater getLayoutInflater(); method public android.view.LayoutInflater getLayoutInflater();
method public android.app.Dialog getWindow(); method public android.app.Dialog getWindow();
method public void hide(); method public void hide();
@@ -28832,6 +28835,7 @@ package android.service.voice {
method public void onTaskStarted(android.content.Intent, int); method public void onTaskStarted(android.content.Intent, int);
method public void onTrimMemory(int); method public void onTrimMemory(int);
method public void setContentView(android.view.View); method public void setContentView(android.view.View);
method public void setDisabledShowContext(int);
method public void setKeepAwake(boolean); method public void setKeepAwake(boolean);
method public void setTheme(int); method public void setTheme(int);
method public void show(android.os.Bundle, int); method public void show(android.os.Bundle, int);

View File

@@ -30934,11 +30934,13 @@ package android.service.voice {
public class VoiceInteractionService extends android.app.Service { public class VoiceInteractionService extends android.app.Service {
ctor public VoiceInteractionService(); ctor public VoiceInteractionService();
method public final android.service.voice.AlwaysOnHotwordDetector createAlwaysOnHotwordDetector(java.lang.String, java.util.Locale, android.service.voice.AlwaysOnHotwordDetector.Callback); method public final android.service.voice.AlwaysOnHotwordDetector createAlwaysOnHotwordDetector(java.lang.String, java.util.Locale, android.service.voice.AlwaysOnHotwordDetector.Callback);
method public int getDisabledShowContext();
method public static boolean isActiveService(android.content.Context, android.content.ComponentName); method public static boolean isActiveService(android.content.Context, android.content.ComponentName);
method public android.os.IBinder onBind(android.content.Intent); method public android.os.IBinder onBind(android.content.Intent);
method public void onLaunchVoiceAssistFromKeyguard(); method public void onLaunchVoiceAssistFromKeyguard();
method public void onReady(); method public void onReady();
method public void onShutdown(); method public void onShutdown();
method public void setDisabledShowContext(int);
method public void showSession(android.os.Bundle, int); method public void showSession(android.os.Bundle, int);
field public static final java.lang.String SERVICE_INTERFACE = "android.service.voice.VoiceInteractionService"; field public static final java.lang.String SERVICE_INTERFACE = "android.service.voice.VoiceInteractionService";
field public static final java.lang.String SERVICE_META_DATA = "android.voice_interaction"; field public static final java.lang.String SERVICE_META_DATA = "android.voice_interaction";
@@ -30950,6 +30952,7 @@ package android.service.voice {
method public void closeSystemDialogs(); method public void closeSystemDialogs();
method public void finish(); method public void finish();
method public android.content.Context getContext(); method public android.content.Context getContext();
method public int getDisabledShowContext();
method public android.view.LayoutInflater getLayoutInflater(); method public android.view.LayoutInflater getLayoutInflater();
method public android.app.Dialog getWindow(); method public android.app.Dialog getWindow();
method public void hide(); method public void hide();
@@ -30981,6 +30984,7 @@ package android.service.voice {
method public void onTaskStarted(android.content.Intent, int); method public void onTaskStarted(android.content.Intent, int);
method public void onTrimMemory(int); method public void onTrimMemory(int);
method public void setContentView(android.view.View); method public void setContentView(android.view.View);
method public void setDisabledShowContext(int);
method public void setKeepAwake(boolean); method public void setKeepAwake(boolean);
method public void setTheme(int); method public void setTheme(int);
method public void show(android.os.Bundle, int); method public void show(android.os.Bundle, int);

View File

@@ -37,7 +37,6 @@ import java.io.FileDescriptor;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.Locale; import java.util.Locale;
/** /**
* Top-level service of the current global voice interactor, which is providing * Top-level service of the current global voice interactor, which is providing
* support for hotwording, the back-end of a {@link android.app.VoiceInteractor}, etc. * support for hotwording, the back-end of a {@link android.app.VoiceInteractor}, etc.
@@ -153,12 +152,40 @@ public class VoiceInteractionService extends Service {
return curComp.equals(service); return curComp.equals(service);
} }
/**
* Set contextual options you would always like to have disabled when a session
* is shown. The flags may be any combination of
* {@link VoiceInteractionSession#SHOW_WITH_ASSIST VoiceInteractionSession.SHOW_WITH_ASSIST} and
* {@link VoiceInteractionSession#SHOW_WITH_SCREENSHOT
* VoiceInteractionSession.SHOW_WITH_SCREENSHOT}.
*/
public void setDisabledShowContext(int flags) {
try {
mSystemService.setDisabledShowContext(flags);
} catch (RemoteException e) {
}
}
/**
* Return the value set by {@link #setDisabledShowContext}.
*/
public int getDisabledShowContext() {
try {
return mSystemService.getDisabledShowContext();
} catch (RemoteException e) {
return 0;
}
}
/** /**
* Request that the associated {@link android.service.voice.VoiceInteractionSession} be * Request that the associated {@link android.service.voice.VoiceInteractionSession} be
* shown to the user, starting it if necessary. * shown to the user, starting it if necessary.
* @param args Arbitrary arguments that will be propagated to the session. * @param args Arbitrary arguments that will be propagated to the session.
* @param flags Indicates additional optional behavior that should be performed. May * @param flags Indicates additional optional behavior that should be performed. May
* be {@link VoiceInteractionSession#SHOW_WITH_ASSIST VoiceInteractionSession.SHOW_WITH_ASSIST} * be any combination of
* {@link VoiceInteractionSession#SHOW_WITH_ASSIST VoiceInteractionSession.SHOW_WITH_ASSIST} and
* {@link VoiceInteractionSession#SHOW_WITH_SCREENSHOT
* VoiceInteractionSession.SHOW_WITH_SCREENSHOT}
* to request that the system generate and deliver assist data on the current foreground * to request that the system generate and deliver assist data on the current foreground
* app as part of showing the session UI. * app as part of showing the session UI.
*/ */

View File

@@ -912,13 +912,39 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
mContentFrame = (FrameLayout)mRootView.findViewById(android.R.id.content); mContentFrame = (FrameLayout)mRootView.findViewById(android.R.id.content);
} }
/**
* Equivalent to {@link VoiceInteractionService#setDisabledShowContext
* VoiceInteractionService.setDisabledShowContext(int)}.
*/
public void setDisabledShowContext(int flags) {
try {
mSystemService.setDisabledShowContext(flags);
} catch (RemoteException e) {
}
}
/**
* Equivalent to {@link VoiceInteractionService#getDisabledShowContext
* VoiceInteractionService.getDisabledShowContext}.
*/
public int getDisabledShowContext() {
try {
return mSystemService.getDisabledShowContext();
} catch (RemoteException e) {
return 0;
}
}
/** /**
* Show the UI for this session. This asks the system to go through the process of showing * Show the UI for this session. This asks the system to go through the process of showing
* your UI, which will eventually culminate in {@link #onShow}. This is similar to calling * your UI, which will eventually culminate in {@link #onShow}. This is similar to calling
* {@link VoiceInteractionService#showSession VoiceInteractionService.showSession}. * {@link VoiceInteractionService#showSession VoiceInteractionService.showSession}.
* @param args Arbitrary arguments that will be propagated {@link #onShow}. * @param args Arbitrary arguments that will be propagated {@link #onShow}.
* @param flags Indicates additional optional behavior that should be performed. May * @param flags Indicates additional optional behavior that should be performed. May
* be {@link VoiceInteractionSession#SHOW_WITH_ASSIST VoiceInteractionSession.SHOW_WITH_ASSIST} * be any combination of
* {@link VoiceInteractionSession#SHOW_WITH_ASSIST VoiceInteractionSession.SHOW_WITH_ASSIST} and
* {@link VoiceInteractionSession#SHOW_WITH_SCREENSHOT
* VoiceInteractionSession.SHOW_WITH_SCREENSHOT}
* to request that the system generate and deliver assist data on the current foreground * to request that the system generate and deliver assist data on the current foreground
* app as part of showing the session UI. * app as part of showing the session UI.
*/ */

View File

@@ -37,6 +37,8 @@ interface IVoiceInteractionManagerService {
void setKeepAwake(IBinder token, boolean keepAwake); void setKeepAwake(IBinder token, boolean keepAwake);
void closeSystemDialogs(IBinder token); void closeSystemDialogs(IBinder token);
void finish(IBinder token); void finish(IBinder token);
void setDisabledShowContext(int flags);
int getDisabledShowContext();
/** /**
* Gets the registered Sound model for keyphrase detection for the current user. * Gets the registered Sound model for keyphrase detection for the current user.

View File

@@ -578,6 +578,44 @@ public class VoiceInteractionManagerService extends SystemService {
} }
} }
@Override
public void setDisabledShowContext(int flags) {
synchronized (this) {
if (mImpl == null) {
Slog.w(TAG, "setDisabledShowContext without running voice interaction service");
return;
}
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long caller = Binder.clearCallingIdentity();
try {
mImpl.setDisabledShowContextLocked(callingPid, callingUid, flags);
} finally {
Binder.restoreCallingIdentity(caller);
}
}
}
@Override
public int getDisabledShowContext() {
synchronized (this) {
if (mImpl == null) {
Slog.w(TAG, "getDisabledShowContext without running voice interaction service");
return 0;
}
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long caller = Binder.clearCallingIdentity();
try {
return mImpl.getDisabledShowContextLocked(callingPid, callingUid);
} finally {
Binder.restoreCallingIdentity(caller);
}
}
}
//----------------- Model management APIs --------------------------------// //----------------- Model management APIs --------------------------------//
@Override @Override

View File

@@ -65,6 +65,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
IVoiceInteractionService mService; IVoiceInteractionService mService;
VoiceInteractionSessionConnection mActiveSession; VoiceInteractionSessionConnection mActiveSession;
int mDisabledShowContext;
final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override @Override
@@ -146,7 +147,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
mActiveSession = new VoiceInteractionSessionConnection(mLock, mSessionComponentName, mActiveSession = new VoiceInteractionSessionConnection(mLock, mSessionComponentName,
mUser, mContext, this, mInfo.getServiceInfo().applicationInfo.uid, mHandler); mUser, mContext, this, mInfo.getServiceInfo().applicationInfo.uid, mHandler);
} }
return mActiveSession.showLocked(args, flags, showCallback); return mActiveSession.showLocked(args, flags, mDisabledShowContext, showCallback);
} }
public boolean hideSessionLocked() { public boolean hideSessionLocked() {
@@ -222,6 +223,24 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
mActiveSession = null; mActiveSession = null;
} }
public void setDisabledShowContextLocked(int callingPid, int callingUid, int flags) {
int activeUid = mInfo.getServiceInfo().applicationInfo.uid;
if (callingUid != activeUid) {
throw new SecurityException("Calling uid " + callingUid
+ " does not match active uid " + activeUid);
}
mDisabledShowContext = flags;
}
public int getDisabledShowContextLocked(int callingPid, int callingUid) {
int activeUid = mInfo.getServiceInfo().applicationInfo.uid;
if (callingUid != activeUid) {
throw new SecurityException("Calling uid " + callingUid
+ " does not match active uid " + activeUid);
}
return mDisabledShowContext;
}
public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args) { public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!mValid) { if (!mValid) {
pw.print(" NOT VALID: "); pw.print(" NOT VALID: ");
@@ -235,6 +254,10 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
pw.print(" mComponent="); pw.println(mComponent.flattenToShortString()); pw.print(" mComponent="); pw.println(mComponent.flattenToShortString());
pw.print(" Session service="); pw.println(mInfo.getSessionService()); pw.print(" Session service="); pw.println(mInfo.getSessionService());
pw.print(" Settings activity="); pw.println(mInfo.getSettingsActivity()); pw.print(" Settings activity="); pw.println(mInfo.getSettingsActivity());
if (mDisabledShowContext != 0) {
pw.print(" mDisabledShowContext=");
pw.println(Integer.toHexString(mDisabledShowContext));
}
pw.print(" mBound="); pw.print(mBound); pw.print(" mService="); pw.println(mService); pw.print(" mBound="); pw.print(mBound); pw.print(" mService="); pw.println(mService);
if (mActiveSession != null) { if (mActiveSession != null) {
pw.println(" Active session:"); pw.println(" Active session:");

View File

@@ -183,7 +183,7 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
} }
} }
public boolean showLocked(Bundle args, int flags, public boolean showLocked(Bundle args, int flags, int disabledContext,
IVoiceInteractionSessionShowCallback showCallback) { IVoiceInteractionSessionShowCallback showCallback) {
if (mBound) { if (mBound) {
if (!mFullyBound) { if (!mFullyBound) {
@@ -200,15 +200,17 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
} }
boolean structureEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(), boolean structureEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1, mUser) != 0 Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1, mUser) != 0
&& isScreenCaptureAllowed; && isScreenCaptureAllowed
&& (disabledContext&VoiceInteractionSession.SHOW_WITH_ASSIST) == 0;
boolean screenshotEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(), boolean screenshotEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
Settings.Secure.ASSIST_SCREENSHOT_ENABLED, 1, mUser) != 0 Settings.Secure.ASSIST_SCREENSHOT_ENABLED, 1, mUser) != 0
&& isScreenCaptureAllowed; && isScreenCaptureAllowed
&& (disabledContext&VoiceInteractionSession.SHOW_WITH_SCREENSHOT) == 0;
mShowArgs = args; mShowArgs = args;
mShowFlags = flags; mShowFlags = flags;
mHaveAssistData = false; mHaveAssistData = false;
boolean needDisclosure = false; boolean needDisclosure = false;
if ((flags& VoiceInteractionSession.SHOW_WITH_ASSIST) != 0) { if ((flags&VoiceInteractionSession.SHOW_WITH_ASSIST) != 0) {
if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ASSIST_STRUCTURE, mCallingUid, if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ASSIST_STRUCTURE, mCallingUid,
mSessionComponentName.getPackageName()) == AppOpsManager.MODE_ALLOWED mSessionComponentName.getPackageName()) == AppOpsManager.MODE_ALLOWED
&& structureEnabled) { && structureEnabled) {
@@ -226,7 +228,7 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
mAssistData = null; mAssistData = null;
} }
mHaveScreenshot = false; mHaveScreenshot = false;
if ((flags& VoiceInteractionSession.SHOW_WITH_SCREENSHOT) != 0) { if ((flags&VoiceInteractionSession.SHOW_WITH_SCREENSHOT) != 0) {
if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ASSIST_SCREENSHOT, mCallingUid, if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ASSIST_SCREENSHOT, mCallingUid,
mSessionComponentName.getPackageName()) == AppOpsManager.MODE_ALLOWED mSessionComponentName.getPackageName()) == AppOpsManager.MODE_ALLOWED
&& screenshotEnabled) { && screenshotEnabled) {

View File

@@ -31,14 +31,19 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true"> android:fitsSystemWindows="true">
<LinearLayout android:id="@+id/top_content" <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="top" android:layout_gravity="top"
android:orientation="horizontal" android:orientation="vertical"
android:background="#ffffffff" android:background="#ffffffff"
android:elevation="8dp" android:elevation="8dp"
> >
<LinearLayout android:id="@+id/top_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<ImageView android:id="@+id/screenshot" <ImageView android:id="@+id/screenshot"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="46dp" android:layout_height="46dp"
@@ -46,6 +51,9 @@
<View android:layout_width="0dp" <View android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_weight="1" /> android:layout_weight="1" />
<CheckBox android:id="@+id/show_options"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button android:id="@+id/do_tree" <Button android:id="@+id/do_tree"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -59,6 +67,21 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/start" /> android:text="@string/start" />
</LinearLayout> </LinearLayout>
<LinearLayout android:id="@+id/options"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<CheckBox android:id="@+id/disallow_structure"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Disallow context" />
<CheckBox android:id="@+id/disallow_screenshot"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Disallow screenshot" />
</LinearLayout>
</LinearLayout>
<LinearLayout android:id="@+id/bottom_content" <LinearLayout android:id="@+id/bottom_content"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@@ -29,6 +29,7 @@ import android.service.voice.VoiceInteractionSession;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
@@ -45,6 +46,10 @@ public class MainInteractionSession extends VoiceInteractionSession
Button mTreeButton; Button mTreeButton;
Button mTextButton; Button mTextButton;
Button mStartButton; Button mStartButton;
CheckBox mOptionsCheck;
View mOptionsContainer;
CheckBox mDisallowAssist;
CheckBox mDisallowScreenshot;
ImageView mScreenshot; ImageView mScreenshot;
ImageView mFullScreenshot; ImageView mFullScreenshot;
Button mConfirmButton; Button mConfirmButton;
@@ -122,15 +127,34 @@ public class MainInteractionSession extends VoiceInteractionSession
mScreenshot = (ImageView)mContentView.findViewById(R.id.screenshot); mScreenshot = (ImageView)mContentView.findViewById(R.id.screenshot);
mScreenshot.setOnClickListener(this); mScreenshot.setOnClickListener(this);
mFullScreenshot = (ImageView)mContentView.findViewById(R.id.full_screenshot); mFullScreenshot = (ImageView)mContentView.findViewById(R.id.full_screenshot);
mOptionsCheck = (CheckBox)mContentView.findViewById(R.id.show_options);
mOptionsCheck.setOnClickListener(this);
mOptionsContainer = mContentView.findViewById(R.id.options);
mDisallowAssist = (CheckBox)mContentView.findViewById(R.id.disallow_structure);
mDisallowAssist.setOnClickListener(this);
mDisallowScreenshot = (CheckBox)mContentView.findViewById(R.id.disallow_screenshot);
mDisallowScreenshot.setOnClickListener(this);
mConfirmButton = (Button)mContentView.findViewById(R.id.confirm); mConfirmButton = (Button)mContentView.findViewById(R.id.confirm);
mConfirmButton.setOnClickListener(this); mConfirmButton.setOnClickListener(this);
mCompleteButton = (Button)mContentView.findViewById(R.id.complete); mCompleteButton = (Button)mContentView.findViewById(R.id.complete);
mCompleteButton.setOnClickListener(this); mCompleteButton.setOnClickListener(this);
mAbortButton = (Button)mContentView.findViewById(R.id.abort); mAbortButton = (Button)mContentView.findViewById(R.id.abort);
mAbortButton.setOnClickListener(this); mAbortButton.setOnClickListener(this);
refreshOptions();
return mContentView; return mContentView;
} }
void refreshOptions() {
if (mOptionsCheck.isChecked()) {
mOptionsContainer.setVisibility(View.VISIBLE);
int flags = getDisabledShowContext();
mDisallowAssist.setChecked((flags & SHOW_WITH_ASSIST) != 0);
mDisallowScreenshot.setChecked((flags & SHOW_WITH_SCREENSHOT) != 0);
} else {
mOptionsContainer.setVisibility(View.GONE);
}
}
public void onHandleAssist(Bundle assistBundle) { public void onHandleAssist(Bundle assistBundle) {
} }
@@ -202,6 +226,24 @@ public class MainInteractionSession extends VoiceInteractionSession
if (mAssistVisualizer != null) { if (mAssistVisualizer != null) {
mAssistVisualizer.logText(); mAssistVisualizer.logText();
} }
} else if (v == mOptionsCheck) {
refreshOptions();
} else if (v == mDisallowAssist) {
int flags = getDisabledShowContext();
if (mDisallowAssist.isChecked()) {
flags |= SHOW_WITH_ASSIST;
} else {
flags &= ~SHOW_WITH_ASSIST;
}
setDisabledShowContext(flags);
} else if (v == mDisallowScreenshot) {
int flags = getDisabledShowContext();
if (mDisallowScreenshot.isChecked()) {
flags |= SHOW_WITH_SCREENSHOT;
} else {
flags &= ~SHOW_WITH_SCREENSHOT;
}
setDisabledShowContext(flags);
} else if (v == mStartButton) { } else if (v == mStartButton) {
mState = STATE_LAUNCHING; mState = STATE_LAUNCHING;
updateState(); updateState();