116ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk/* 216ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk * Copyright (C) 2015 The Android Open Source Project 316ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk * 416ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk * Licensed under the Apache License, Version 2.0 (the "License"); 516ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk * you may not use this file except in compliance with the License. 616ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk * You may obtain a copy of the License at 716ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk * 816ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk * http://www.apache.org/licenses/LICENSE-2.0 916ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk * 1016ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk * Unless required by applicable law or agreed to in writing, software 1116ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk * distributed under the License is distributed on an "AS IS" BASIS, 1216ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1316ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk * See the License for the specific language governing permissions and 1416ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk * limitations under the License. 1516ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk */ 1616ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monkpackage com.android.systemui.tuner; 1716ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 1816ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monkimport android.content.ContentResolver; 1916ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monkimport android.content.Context; 2016ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monkimport android.content.Intent; 2116ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monkimport android.database.ContentObserver; 2216ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monkimport android.os.Bundle; 2316ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monkimport android.os.Handler; 2416ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monkimport android.os.Looper; 2516ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monkimport android.provider.Settings; 2687ccd55e8a90ff5d1c30f852941d523a83ab735aJason Monkimport android.support.v14.preference.PreferenceFragment; 2787ccd55e8a90ff5d1c30f852941d523a83ab735aJason Monkimport android.support.v14.preference.SwitchPreference; 2887ccd55e8a90ff5d1c30f852941d523a83ab735aJason Monkimport android.support.v7.preference.Preference; 2987ccd55e8a90ff5d1c30f852941d523a83ab735aJason Monkimport android.support.v7.preference.Preference.OnPreferenceChangeListener; 3087ccd55e8a90ff5d1c30f852941d523a83ab735aJason Monkimport android.support.v7.preference.PreferenceScreen; 31431ad737a4752e9325894211c28bb0f0f97c00a7Jason Monkimport android.view.MenuItem; 3216ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 33a403159a3bb693088c127e4ee5955fa940e75950Jason Monkimport com.android.internal.logging.MetricsLogger; 34383db5ebcc3a4a615faf249bf4f126f42e80b82eTamas Berghammerimport com.android.internal.logging.nano.MetricsProto.MetricsEvent; 3516ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monkimport com.android.systemui.DemoMode; 3616ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monkimport com.android.systemui.R; 3716ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 3816ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monkpublic class DemoModeFragment extends PreferenceFragment implements OnPreferenceChangeListener { 3916ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 4016ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk private static final String DEMO_MODE_ON = "sysui_tuner_demo_on"; 4116ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 4216ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk private static final String[] STATUS_ICONS = { 4316ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk "volume", 4416ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk "bluetooth", 4516ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk "location", 4616ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk "alarm", 4716ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk "zen", 4816ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk "sync", 4916ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk "tty", 5016ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk "eri", 5116ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk "mute", 5216ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk "speakerphone", 5316ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk "managed_profile", 5416ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk }; 5516ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 5616ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk private SwitchPreference mEnabledSwitch; 5716ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk private SwitchPreference mOnSwitch; 5816ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 5916ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk @Override 6087ccd55e8a90ff5d1c30f852941d523a83ab735aJason Monk public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { 6116ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk Context context = getContext(); 6216ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk mEnabledSwitch = new SwitchPreference(context); 6316ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk mEnabledSwitch.setTitle(R.string.enable_demo_mode); 6416ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk mEnabledSwitch.setOnPreferenceChangeListener(this); 6516ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk mOnSwitch = new SwitchPreference(context); 6616ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk mOnSwitch.setTitle(R.string.show_demo_mode); 6716ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk mOnSwitch.setEnabled(false); 6816ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk mOnSwitch.setOnPreferenceChangeListener(this); 6916ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 7016ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(context); 7116ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk screen.addPreference(mEnabledSwitch); 7216ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk screen.addPreference(mOnSwitch); 7316ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk setPreferenceScreen(screen); 7416ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 7516ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk updateDemoModeEnabled(); 7616ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk updateDemoModeOn(); 7716ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk ContentResolver contentResolver = getContext().getContentResolver(); 78431ad737a4752e9325894211c28bb0f0f97c00a7Jason Monk contentResolver.registerContentObserver(Settings.Global.getUriFor( 79431ad737a4752e9325894211c28bb0f0f97c00a7Jason Monk DemoMode.DEMO_MODE_ALLOWED), false, mDemoModeObserver); 8016ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk contentResolver.registerContentObserver(Settings.Global.getUriFor(DEMO_MODE_ON), false, 8116ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk mDemoModeObserver); 82431ad737a4752e9325894211c28bb0f0f97c00a7Jason Monk setHasOptionsMenu(true); 83431ad737a4752e9325894211c28bb0f0f97c00a7Jason Monk } 84431ad737a4752e9325894211c28bb0f0f97c00a7Jason Monk 85431ad737a4752e9325894211c28bb0f0f97c00a7Jason Monk @Override 86431ad737a4752e9325894211c28bb0f0f97c00a7Jason Monk public boolean onOptionsItemSelected(MenuItem item) { 87431ad737a4752e9325894211c28bb0f0f97c00a7Jason Monk switch (item.getItemId()) { 88431ad737a4752e9325894211c28bb0f0f97c00a7Jason Monk case android.R.id.home: 89431ad737a4752e9325894211c28bb0f0f97c00a7Jason Monk getFragmentManager().popBackStack(); 90431ad737a4752e9325894211c28bb0f0f97c00a7Jason Monk break; 91431ad737a4752e9325894211c28bb0f0f97c00a7Jason Monk } 92431ad737a4752e9325894211c28bb0f0f97c00a7Jason Monk return super.onOptionsItemSelected(item); 9316ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk } 9416ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 9516ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk @Override 96a403159a3bb693088c127e4ee5955fa940e75950Jason Monk public void onResume() { 97a403159a3bb693088c127e4ee5955fa940e75950Jason Monk super.onResume(); 98f6e9228b8a97603d3ceb8f0d61e8d87cf19bd21fChris Wren MetricsLogger.visibility(getContext(), MetricsEvent.TUNER_DEMO_MODE, true); 99a403159a3bb693088c127e4ee5955fa940e75950Jason Monk } 100a403159a3bb693088c127e4ee5955fa940e75950Jason Monk 101a403159a3bb693088c127e4ee5955fa940e75950Jason Monk @Override 102a403159a3bb693088c127e4ee5955fa940e75950Jason Monk public void onPause() { 103a403159a3bb693088c127e4ee5955fa940e75950Jason Monk super.onPause(); 104f6e9228b8a97603d3ceb8f0d61e8d87cf19bd21fChris Wren MetricsLogger.visibility(getContext(), MetricsEvent.TUNER_DEMO_MODE, false); 105a403159a3bb693088c127e4ee5955fa940e75950Jason Monk } 106a403159a3bb693088c127e4ee5955fa940e75950Jason Monk 107a403159a3bb693088c127e4ee5955fa940e75950Jason Monk @Override 10816ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk public void onDestroy() { 10916ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk getContext().getContentResolver().unregisterContentObserver(mDemoModeObserver); 11016ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk super.onDestroy(); 11116ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk } 11216ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 11316ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk private void updateDemoModeEnabled() { 11416ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk boolean enabled = Settings.Global.getInt(getContext().getContentResolver(), 115431ad737a4752e9325894211c28bb0f0f97c00a7Jason Monk DemoMode.DEMO_MODE_ALLOWED, 0) != 0; 11616ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk mEnabledSwitch.setChecked(enabled); 11716ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk mOnSwitch.setEnabled(enabled); 11816ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk } 11916ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 12016ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk private void updateDemoModeOn() { 12116ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk boolean enabled = Settings.Global.getInt(getContext().getContentResolver(), 12216ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk DEMO_MODE_ON, 0) != 0; 12316ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk mOnSwitch.setChecked(enabled); 12416ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk } 12516ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 12616ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk @Override 12716ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk public boolean onPreferenceChange(Preference preference, Object newValue) { 128a403159a3bb693088c127e4ee5955fa940e75950Jason Monk boolean enabled = newValue == Boolean.TRUE; 12916ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk if (preference == mEnabledSwitch) { 130a403159a3bb693088c127e4ee5955fa940e75950Jason Monk if (!enabled) { 13133b60bb45ff45540c4bd4f5d74f3ca5489f02088Jason Monk // Make sure we aren't in demo mode when disabling it. 13233b60bb45ff45540c4bd4f5d74f3ca5489f02088Jason Monk mOnSwitch.setChecked(false); 13333b60bb45ff45540c4bd4f5d74f3ca5489f02088Jason Monk stopDemoMode(); 13433b60bb45ff45540c4bd4f5d74f3ca5489f02088Jason Monk } 135f6e9228b8a97603d3ceb8f0d61e8d87cf19bd21fChris Wren MetricsLogger.action(getContext(), MetricsEvent.TUNER_DEMO_MODE_ENABLED, enabled); 136a403159a3bb693088c127e4ee5955fa940e75950Jason Monk setGlobal(DemoMode.DEMO_MODE_ALLOWED, enabled ? 1 : 0); 13716ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk } else if (preference == mOnSwitch) { 138f6e9228b8a97603d3ceb8f0d61e8d87cf19bd21fChris Wren MetricsLogger.action(getContext(), MetricsEvent.TUNER_DEMO_MODE_ON, enabled); 139a403159a3bb693088c127e4ee5955fa940e75950Jason Monk if (enabled) { 14016ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk startDemoMode(); 14116ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk } else { 14216ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk stopDemoMode(); 14316ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk } 14416ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk } else { 14516ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk return false; 14616ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk } 14716ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk return true; 14816ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk } 14916ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 15016ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk private void startDemoMode() { 15116ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk Intent intent = new Intent(DemoMode.ACTION_DEMO); 15216ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 15316ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_ENTER); 15416ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk getContext().sendBroadcast(intent); 15516ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 15616ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_CLOCK); 157f72545a25c6e8b0e9cdeb1b3c266e954a49a9ebeDan Sandler 158f72545a25c6e8b0e9cdeb1b3c266e954a49a9ebeDan Sandler String demoTime = "1010"; // 10:10, a classic choice of horologists 159f72545a25c6e8b0e9cdeb1b3c266e954a49a9ebeDan Sandler try { 160f72545a25c6e8b0e9cdeb1b3c266e954a49a9ebeDan Sandler String[] versionParts = android.os.Build.VERSION.RELEASE.split("\\."); 161f72545a25c6e8b0e9cdeb1b3c266e954a49a9ebeDan Sandler int majorVersion = Integer.valueOf(versionParts[0]); 162f72545a25c6e8b0e9cdeb1b3c266e954a49a9ebeDan Sandler demoTime = String.format("%02d00", majorVersion % 24); 163f72545a25c6e8b0e9cdeb1b3c266e954a49a9ebeDan Sandler } catch (IllegalArgumentException ex) { 164f72545a25c6e8b0e9cdeb1b3c266e954a49a9ebeDan Sandler } 165f72545a25c6e8b0e9cdeb1b3c266e954a49a9ebeDan Sandler intent.putExtra("hhmm", demoTime); 16616ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk getContext().sendBroadcast(intent); 16716ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 16816ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_NETWORK); 16916ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk intent.putExtra("wifi", "show"); 17016ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk intent.putExtra("mobile", "show"); 17116ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk intent.putExtra("sims", "1"); 17216ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk intent.putExtra("nosim", "false"); 17316ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk intent.putExtra("level", "4"); 1745c88ffb5072b96662b34cb8139151707f424318aKenneth Westin intent.putExtra("datatype", "lte"); 17516ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk getContext().sendBroadcast(intent); 17616ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 177259e06f58225e70716d3370d123e8dca830206a7Jason Monk // Need to send this after so that the sim controller already exists. 178259e06f58225e70716d3370d123e8dca830206a7Jason Monk intent.putExtra("fully", "true"); 179259e06f58225e70716d3370d123e8dca830206a7Jason Monk getContext().sendBroadcast(intent); 180259e06f58225e70716d3370d123e8dca830206a7Jason Monk 18116ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_BATTERY); 18216ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk intent.putExtra("level", "100"); 18316ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk intent.putExtra("plugged", "false"); 18416ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk getContext().sendBroadcast(intent); 18516ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 18616ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_STATUS); 18716ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk for (String icon : STATUS_ICONS) { 18816ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk intent.putExtra(icon, "hide"); 18916ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk } 19016ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk getContext().sendBroadcast(intent); 19116ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 19216ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_NOTIFICATIONS); 19316ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk intent.putExtra("visible", "false"); 19416ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk getContext().sendBroadcast(intent); 19516ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 19616ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk setGlobal(DEMO_MODE_ON, 1); 19716ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk } 19816ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 19916ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk private void stopDemoMode() { 20016ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk Intent intent = new Intent(DemoMode.ACTION_DEMO); 20116ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_EXIT); 20216ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk getContext().sendBroadcast(intent); 20316ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk setGlobal(DEMO_MODE_ON, 0); 20416ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk } 20516ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 20616ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk private void setGlobal(String key, int value) { 20716ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk Settings.Global.putInt(getContext().getContentResolver(), key, value); 20816ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk } 20916ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk 21016ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk private final ContentObserver mDemoModeObserver = 21116ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk new ContentObserver(new Handler(Looper.getMainLooper())) { 21216ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk public void onChange(boolean selfChange) { 21316ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk updateDemoModeEnabled(); 21416ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk updateDemoModeOn(); 21516ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk }; 21616ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk }; 21716ada3df306f3efcfc748fcd23e78cbe6375efa6Jason Monk} 218