diff options
author | cretin45 <cretin45@gmail.com> | 2015-05-07 16:21:10 -0700 |
---|---|---|
committer | cretin45 <cretin45@gmail.com> | 2015-05-08 11:44:34 -0700 |
commit | 7710855b726a921d7fd1e85aeeb4b20fee998923 (patch) | |
tree | a7203ba380b5189a47ae6cf25be9ffe3c46294d3 | |
parent | 4d08b90df38a90a0ec077412f92b0dabb594e056 (diff) | |
download | packages_apps_SetupWizard-7710855b726a921d7fd1e85aeeb4b20fee998923.tar.gz packages_apps_SetupWizard-7710855b726a921d7fd1e85aeeb4b20fee998923.tar.bz2 packages_apps_SetupWizard-7710855b726a921d7fd1e85aeeb4b20fee998923.zip |
SetupWizard: Add kill switch implementation
Change-Id: I1335cddf0dcc94eb8d2defeebdc47cb61abffd06
18 files changed, 207 insertions, 5 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index d4a7826..d575831 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -47,6 +47,7 @@ <uses-permission android:name="cyanogenmod.permission.FINISH_SETUP" /> <uses-permission android:name="cyanogenmod.permission.LEGALESE" /> <uses-permission android:name="com.cyngn.cmstats.SEND_ANALYTICS" /> + <uses-permission android:name="com.cyanogen.permission.REQUEST_KILL_SWITCH_OP" /> <permission android:name="cyanogenmod.permission.PROTECTED_APP" diff --git a/res/drawable-hdpi/cross.png b/res/drawable-hdpi/cross.png Binary files differnew file mode 100755 index 0000000..ad8e5d9 --- /dev/null +++ b/res/drawable-hdpi/cross.png diff --git a/res/drawable-hdpi/tick.png b/res/drawable-hdpi/tick.png Binary files differnew file mode 100755 index 0000000..1564a5b --- /dev/null +++ b/res/drawable-hdpi/tick.png diff --git a/res/drawable-mdpi/cross.png b/res/drawable-mdpi/cross.png Binary files differnew file mode 100755 index 0000000..a5bca90 --- /dev/null +++ b/res/drawable-mdpi/cross.png diff --git a/res/drawable-mdpi/tick.png b/res/drawable-mdpi/tick.png Binary files differnew file mode 100755 index 0000000..779b159 --- /dev/null +++ b/res/drawable-mdpi/tick.png diff --git a/res/drawable-xhdpi/cross.png b/res/drawable-xhdpi/cross.png Binary files differnew file mode 100755 index 0000000..d5cac0a --- /dev/null +++ b/res/drawable-xhdpi/cross.png diff --git a/res/drawable-xhdpi/tick.png b/res/drawable-xhdpi/tick.png Binary files differnew file mode 100755 index 0000000..0e10e6d --- /dev/null +++ b/res/drawable-xhdpi/tick.png diff --git a/res/drawable-xxhdpi/cross.png b/res/drawable-xxhdpi/cross.png Binary files differnew file mode 100755 index 0000000..9c47e16 --- /dev/null +++ b/res/drawable-xxhdpi/cross.png diff --git a/res/drawable-xxhdpi/tick.png b/res/drawable-xxhdpi/tick.png Binary files differnew file mode 100755 index 0000000..f398a15 --- /dev/null +++ b/res/drawable-xxhdpi/tick.png diff --git a/res/drawable-xxxhdpi/cross.png b/res/drawable-xxxhdpi/cross.png Binary files differnew file mode 100755 index 0000000..0a2800d --- /dev/null +++ b/res/drawable-xxxhdpi/cross.png diff --git a/res/drawable-xxxhdpi/tick.png b/res/drawable-xxxhdpi/tick.png Binary files differnew file mode 100755 index 0000000..050fa9f --- /dev/null +++ b/res/drawable-xxxhdpi/tick.png diff --git a/res/layout/setup_cyanogen_services.xml b/res/layout/setup_cyanogen_services.xml index ba16627..36837bb 100644 --- a/res/layout/setup_cyanogen_services.xml +++ b/res/layout/setup_cyanogen_services.xml @@ -50,6 +50,58 @@ android:text="@string/services_explanation" android:clickable="true"/> + <LinearLayout + android:id="@+id/killswitch" + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingLeft="@dimen/location_margin_left" + android:paddingRight="@dimen/content_margin_right" + android:background="?android:attr/selectableItemBackground"> + + + <ImageView + android:id="@+id/killswitch_check" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="5dp" + android:paddingLeft="8dp" + android:paddingRight="@dimen/location_text_margin_left" + android:layout_gravity="center|top" + android:src="@drawable/tick"/> + + <RelativeLayout + android:layout_width="0px" + android:layout_height="wrap_content" + android:layout_weight="1" + android:gravity="top" + android:layout_marginLeft="@dimen/location_text_margin_left" + android:layout_marginRight="@dimen/location_text_margin_right" + android:paddingBottom="@dimen/content_margin_bottom"> + + <TextView + android:id="@+id/killswitch_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textSize="15sp" + android:lineSpacingExtra="@dimen/setup_line_spacing" + android:fadingEdge="horizontal" + android:text="@string/setup_require_cyanogen_label"/> + + <TextView + android:id="@+id/killswitch_summary" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_below="@+id/killswitch_title" + android:layout_alignStart="@+id/killswitch_title" + android:textSize="15sp" + android:lineSpacingExtra="@dimen/setup_line_spacing" + android:textColor="?android:attr/textColorSecondary" + android:text="@string/setup_device_locked_instructions"/> + </RelativeLayout> + + </LinearLayout> + <!-- Whether or not to enable metrics --> <LinearLayout android:id="@+id/metrics" diff --git a/res/values/strings.xml b/res/values/strings.xml index 4a106be..2607b9b 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -79,4 +79,10 @@ <string name="services_os_nav_keys_label"><b>Use on screen navigation keys</b> instead of hardware keys.</string> <string name="services_use_secure_sms">Use secure SMS</string> <string name="services_secure_sms_label"><xliff:g id="name" example="Use secure SMS">%s</xliff:g> to encrypt SMS conversations with other users using secure SMS on a <xliff:g id="name" example="CyanogenMod">%s</xliff:g> device.</string> + + <string name="setup_unlock">Unlock</string> + <string name="setup_device_locked">This device has been locked by the user.</string> + <string name="setup_require_cyanogen_label"><b>Require your Cyanogen OS account password</b> in order to use your device even after a factory reset.</string> + <string name="setup_device_locked_instructions"><i>To turn this feature off/on, please go to Settings > Security</i></string> + <string name="setup_warning_skip_anyway">Without a Cyanogen OS Account, you won\'t be able to:\n\nCustomize your phone with new icons, wallpapers and more in the Themes app\n\nLocate or remotely erase your phone if it\'s lost</string> </resources> diff --git a/src/com/cyanogenmod/setupwizard/SetupWizardApp.java b/src/com/cyanogenmod/setupwizard/SetupWizardApp.java index a1d644b..82b466d 100644 --- a/src/com/cyanogenmod/setupwizard/SetupWizardApp.java +++ b/src/com/cyanogenmod/setupwizard/SetupWizardApp.java @@ -34,6 +34,7 @@ public class SetupWizardApp extends Application { public static final String ACTION_FINISHED = "com.cyanogenmod.setupwizard.SETUP_FINISHED"; + public static final String ACCOUNT_TYPE_CYANOGEN = "com.cyanogen"; public static final String ACCOUNT_TYPE_GMS = "com.google"; public static final String ACTION_SETUP_WIFI = "com.android.net.wifi.SETUP_WIFI_NETWORK"; @@ -46,6 +47,8 @@ public class SetupWizardApp extends Application { public static final String EXTRA_USE_IMMERSIVE = "useImmersiveMode"; public static final String EXTRA_THEME = "theme"; public static final String EXTRA_MATERIAL_LIGHT = "material_light"; + public static final String EXTRA_CKSOP = "cksOp"; + public static final String EXTRA_LOGIN_FOR_KILL_SWITCH = "authCks"; private static final String KEY_DETECT_CAPTIVE_PORTAL = "captive_portal_detection_enabled"; @@ -61,11 +64,14 @@ public class SetupWizardApp extends Application { public static final int REQUEST_CODE_SETUP_CYANOGEN= 3; public static final int REQUEST_CODE_SETUP_CAPTIVE_PORTAL= 4; public static final int REQUEST_CODE_SETUP_BLUETOOTH= 5; + public static final int REQUEST_CODE_UNLOCK = 6; public static final int RADIO_READY_TIMEOUT = 10 * 1000; private boolean mIsRadioReady = false; + private boolean mIsAuthorized = false; + private StatusBarManager mStatusBarManager; private final Handler mHandler = new Handler(); @@ -114,6 +120,14 @@ public class SetupWizardApp extends Application { mIsRadioReady = radioReady; } + public boolean isAuthorized() { + return mIsAuthorized; + } + + public void setIsAuthorized(boolean isAuthorized) { + mIsAuthorized = isAuthorized; + } + public void disableStatusBar() { mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND | StatusBarManager.DISABLE_NOTIFICATION_ALERTS | StatusBarManager.DISABLE_NOTIFICATION_TICKER | StatusBarManager.DISABLE_RECENT | StatusBarManager.DISABLE_HOME diff --git a/src/com/cyanogenmod/setupwizard/setup/CyanogenServicesPage.java b/src/com/cyanogenmod/setupwizard/setup/CyanogenServicesPage.java index 479f2be..e71dd79 100644 --- a/src/com/cyanogenmod/setupwizard/setup/CyanogenServicesPage.java +++ b/src/com/cyanogenmod/setupwizard/setup/CyanogenServicesPage.java @@ -101,6 +101,9 @@ public class CyanogenServicesPage extends SetupPage { resultCode == Activity.RESULT_OK ? "success" : "skipped"); if (SetupWizardUtils.accountExists(mContext, mContext.getString(R.string.cm_account_type))) { + if (SetupWizardUtils.isDeviceLocked()) { + ((SetupWizardApp) mContext.getApplicationContext()).setIsAuthorized(true); + } setHidden(true); } getCallbacks().onNextPage(); diff --git a/src/com/cyanogenmod/setupwizard/setup/CyanogenSettingsPage.java b/src/com/cyanogenmod/setupwizard/setup/CyanogenSettingsPage.java index bdc3076..86906da 100644 --- a/src/com/cyanogenmod/setupwizard/setup/CyanogenSettingsPage.java +++ b/src/com/cyanogenmod/setupwizard/setup/CyanogenSettingsPage.java @@ -42,6 +42,7 @@ import android.view.IWindowManager; import android.view.View; import android.view.WindowManagerGlobal; import android.widget.CheckBox; +import android.widget.ImageView; import android.widget.TextView; import com.cyanogenmod.setupwizard.R; @@ -213,6 +214,9 @@ public class CyanogenSettingsPage extends SetupPage { public static class CyanogenSettingsFragment extends SetupPageFragment { + private View mKillSwitchView; + private TextView mKillSwitchTitle; + private ImageView mKillSwitchStatus; private View mMetricsRow; private View mDefaultThemeRow; private View mNavKeysRow; @@ -287,6 +291,21 @@ public class CyanogenSettingsPage extends SetupPage { privacyPolicy.setMovementMethod(LinkMovementMethod.getInstance()); privacyPolicy.setText(ss); + mKillSwitchView = mRootView.findViewById(R.id.killswitch); + mKillSwitchTitle = (TextView)mRootView.findViewById(R.id.killswitch_title); + mKillSwitchStatus = (ImageView)mRootView.findViewById(R.id.killswitch_check); + if (hideKillSwitch()) { + mKillSwitchView.setVisibility(View.GONE); + } else { + if (SetupWizardUtils.isDeviceLocked()) { + mKillSwitchTitle.setEnabled(true); + mKillSwitchStatus.setImageResource(R.drawable.tick); + } else { + mKillSwitchTitle.setEnabled(false); + mKillSwitchStatus.setImageResource(R.drawable.cross); + } + } + mMetricsRow = mRootView.findViewById(R.id.metrics); mMetricsRow.setOnClickListener(mMetricsClickListener); String metricsHelpImproveCM = @@ -414,5 +433,9 @@ public class CyanogenSettingsPage extends SetupPage { } } + private static boolean hideKillSwitch() { + return !SetupWizardUtils.hasKillSwitch(); + } + } } diff --git a/src/com/cyanogenmod/setupwizard/setup/WelcomePage.java b/src/com/cyanogenmod/setupwizard/setup/WelcomePage.java index 1f63878..3f01e53 100644 --- a/src/com/cyanogenmod/setupwizard/setup/WelcomePage.java +++ b/src/com/cyanogenmod/setupwizard/setup/WelcomePage.java @@ -16,6 +16,10 @@ package com.cyanogenmod.setupwizard.setup; +import android.accounts.AccountManager; +import android.accounts.AccountManagerCallback; +import android.accounts.AccountManagerFuture; +import android.app.Activity; import android.app.ActivityOptions; import android.app.Fragment; import android.app.FragmentManager; @@ -25,14 +29,17 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.os.Bundle; import android.os.Handler; +import android.util.Log; import android.view.View; import android.widget.ArrayAdapter; import android.widget.NumberPicker; import com.cyanogenmod.setupwizard.R; +import com.cyanogenmod.setupwizard.SetupWizardApp; import com.cyanogenmod.setupwizard.cmstats.SetupStats; import com.cyanogenmod.setupwizard.ui.LocalePicker; import com.cyanogenmod.setupwizard.ui.SetupPageFragment; +import com.cyanogenmod.setupwizard.util.SetupWizardUtils; import java.util.Locale; @@ -42,21 +49,23 @@ public class WelcomePage extends SetupPage { private static final String ACTION_EMERGENCY_DIAL = "com.android.phone.EmergencyDialer.DIAL"; + private WelcomeFragment mWelcomeFragment; + public WelcomePage(Context context, SetupDataCallbacks callbacks) { super(context, callbacks); } @Override public Fragment getFragment(FragmentManager fragmentManager, int action) { - Fragment fragment = fragmentManager.findFragmentByTag(getKey()); - if (fragment == null) { + mWelcomeFragment = (WelcomeFragment)fragmentManager.findFragmentByTag(getKey()); + if (mWelcomeFragment == null) { Bundle args = new Bundle(); args.putString(Page.KEY_PAGE_ARGUMENT, getKey()); args.putInt(Page.KEY_PAGE_ACTION, action); - fragment = new WelcomeFragment(); - fragment.setArguments(args); + mWelcomeFragment = new WelcomeFragment(); + mWelcomeFragment.setArguments(args); } - return fragment; + return mWelcomeFragment; } @Override @@ -65,6 +74,16 @@ public class WelcomePage extends SetupPage { } @Override + public boolean doNextAction() { + if (isLocked()) { + confirmCyanogenCredentials(mWelcomeFragment); + return true; + } else { + return super.doNextAction(); + } + } + + @Override public boolean doPreviousAction() { Intent intent = new Intent(ACTION_EMERGENCY_DIAL); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK @@ -82,15 +101,65 @@ public class WelcomePage extends SetupPage { } @Override + public boolean onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == SetupWizardApp.REQUEST_CODE_UNLOCK) { + if (resultCode == Activity.RESULT_OK) { + ((SetupWizardApp) mContext.getApplicationContext()).setIsAuthorized(true); + getCallbacks().onNextPage(); + return true; + } + } + return false; + } + + @Override public String getKey() { return TAG; } @Override + public int getNextButtonTitleResId() { + if (isLocked()) { + return R.string.setup_unlock; + } else { + return R.string.next; + } + } + + @Override public int getPrevButtonTitleResId() { return R.string.emergency_call; } + private void confirmCyanogenCredentials(final Fragment fragment) { + AccountManager accountManager = AccountManager.get(mContext); + accountManager.editProperties(SetupWizardApp.ACCOUNT_TYPE_CYANOGEN, null, + new AccountManagerCallback<Bundle>() { + public void run(AccountManagerFuture<Bundle> f) { + try { + Bundle b = f.getResult(); + Intent i = b.getParcelable(AccountManager.KEY_INTENT); + i.putExtra(SetupWizardApp.EXTRA_FIRST_RUN, true); + i.putExtra(SetupWizardApp.EXTRA_SHOW_BUTTON_BAR, true); + i.putExtra(SetupWizardApp.EXTRA_USE_IMMERSIVE, true); + i.putExtra(SetupWizardApp.EXTRA_LOGIN_FOR_KILL_SWITCH, true); + fragment.startActivityForResult(i, + SetupWizardApp.REQUEST_CODE_UNLOCK); + } catch (Throwable t) { + Log.e(getKey(), "confirmCredentials failed", t); + } + } + }, null); + } + + private boolean isLocked() { + boolean isAuthorized = ((SetupWizardApp) mContext.getApplicationContext()).isAuthorized(); + if (SetupWizardUtils.isDeviceLocked()) { + return !isAuthorized; + } + return false; + } + public static class WelcomeFragment extends SetupPageFragment { private ArrayAdapter<com.android.internal.app.LocalePicker.LocaleInfo> mLocaleAdapter; diff --git a/src/com/cyanogenmod/setupwizard/util/SetupWizardUtils.java b/src/com/cyanogenmod/setupwizard/util/SetupWizardUtils.java index 19ce2e8..113e204 100644 --- a/src/com/cyanogenmod/setupwizard/util/SetupWizardUtils.java +++ b/src/com/cyanogenmod/setupwizard/util/SetupWizardUtils.java @@ -17,6 +17,7 @@ package com.cyanogenmod.setupwizard.util; import android.accounts.AccountManager; +import android.app.AppGlobals; import android.content.ComponentName; import android.content.Context; import android.content.pm.ComponentInfo; @@ -25,6 +26,8 @@ import android.content.pm.PackageManager; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.wifi.WifiManager; +import android.os.IBinder; +import android.os.ServiceManager; import android.os.UserHandle; import android.os.UserManager; import android.telephony.ServiceState; @@ -32,6 +35,7 @@ import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.util.Log; +import com.android.internal.os.IKillSwitchService; import com.cyanogenmod.setupwizard.SetupWizardApp; import com.google.android.gms.common.ConnectionResult; @@ -124,6 +128,36 @@ public class SetupWizardUtils { return true; } + public static boolean isDeviceLocked() { + IBinder b = ServiceManager.getService(Context.KILLSWITCH_SERVICE); + IKillSwitchService service = IKillSwitchService.Stub.asInterface(b); + if (service != null) { + try { + return service.isDeviceLocked(); + } catch (Exception e) { + // silently fail + } + } + return false; + } + + public static boolean hasKillSwitch() { + IBinder b = ServiceManager.getService(Context.KILLSWITCH_SERVICE); + IKillSwitchService service = IKillSwitchService.Stub.asInterface(b); + if (service != null) { + try { + return service.hasKillSwitch(); + } catch (Exception e) { + // silently fail + } + } + return false; + } + + public static boolean hasAuthorized() { + return ((SetupWizardApp) AppGlobals.getInitialApplication()).isAuthorized(); + } + public static boolean isRadioReady(Context context, ServiceState state) { final SetupWizardApp setupWizardApp = (SetupWizardApp)context.getApplicationContext(); if (setupWizardApp.isRadioReady()) { |