Home | History | Annotate | Download | only in settings
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.settings;
     18 
     19 import android.annotation.Nullable;
     20 import android.app.Activity;
     21 import android.app.StatusBarManager;
     22 import android.content.Context;
     23 import android.content.Intent;
     24 import android.os.Bundle;
     25 import android.os.Handler;
     26 import android.os.IBinder;
     27 import android.os.ServiceManager;
     28 import android.os.UserHandle;
     29 import android.os.storage.IStorageManager;
     30 import android.provider.Settings;
     31 import android.util.Log;
     32 import android.view.LayoutInflater;
     33 import android.view.View;
     34 import android.view.ViewGroup;
     35 import android.widget.Button;
     36 
     37 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
     38 import com.android.internal.widget.LockPatternUtils;
     39 import com.android.settings.core.InstrumentedFragment;
     40 
     41 import java.util.Locale;
     42 
     43 public class CryptKeeperConfirm extends InstrumentedFragment {
     44 
     45     private static final String TAG = "CryptKeeperConfirm";
     46 
     47     @Override
     48     public int getMetricsCategory() {
     49         return MetricsEvent.CRYPT_KEEPER_CONFIRM;
     50     }
     51 
     52     public static class Blank extends Activity {
     53         private Handler mHandler = new Handler();
     54 
     55         @Override
     56         public void onCreate(Bundle savedInstanceState) {
     57             super.onCreate(savedInstanceState);
     58 
     59             setContentView(R.layout.crypt_keeper_blank);
     60 
     61             if (Utils.isMonkeyRunning()) {
     62                 finish();
     63             }
     64 
     65             StatusBarManager sbm = (StatusBarManager) getSystemService(Context.STATUS_BAR_SERVICE);
     66             sbm.disable(StatusBarManager.DISABLE_EXPAND
     67                     | StatusBarManager.DISABLE_NOTIFICATION_ICONS
     68                     | StatusBarManager.DISABLE_NOTIFICATION_ALERTS
     69                     | StatusBarManager.DISABLE_SYSTEM_INFO
     70                     | StatusBarManager.DISABLE_HOME
     71                     | StatusBarManager.DISABLE_SEARCH
     72                     | StatusBarManager.DISABLE_RECENT
     73                     | StatusBarManager.DISABLE_BACK);
     74 
     75             // Post a delayed message in 700 milliseconds to enable encryption.
     76             // NOTE: The animation on this activity is set for 500 milliseconds
     77             // I am giving it a little extra time to complete.
     78             mHandler.postDelayed(new Runnable() {
     79                 public void run() {
     80                     IBinder service = ServiceManager.getService("mount");
     81                     if (service == null) {
     82                         Log.e("CryptKeeper", "Failed to find the mount service");
     83                         finish();
     84                         return;
     85                     }
     86 
     87                     IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
     88                     try {
     89                         Bundle args = getIntent().getExtras();
     90                         storageManager.encryptStorage(args.getInt("type", -1), args.getString("password"));
     91                     } catch (Exception e) {
     92                         Log.e("CryptKeeper", "Error while encrypting...", e);
     93                     }
     94                 }
     95             }, 700);
     96         }
     97     }
     98 
     99     private View mContentView;
    100     private Button mFinalButton;
    101     private Button.OnClickListener mFinalClickListener = new Button.OnClickListener() {
    102 
    103         public void onClick(View v) {
    104             if (Utils.isMonkeyRunning()) {
    105                 return;
    106             }
    107 
    108             /* WARNING - nasty hack!
    109                Settings for the lock screen are not available to the crypto
    110                screen (CryptKeeper) at boot. We duplicate the ones that
    111                CryptKeeper needs to the crypto key/value store when they are
    112                modified (see LockPatternUtils).
    113                However, prior to encryption, the crypto key/value store is not
    114                persisted across reboots, thus modified settings are lost to
    115                CryptKeeper.
    116                In order to make sure CryptKeeper had the correct settings after
    117                first encrypting, we thus need to rewrite them, which ensures the
    118                crypto key/value store is up to date. On encryption, this store
    119                is then persisted, and the settings will be there on future
    120                reboots.
    121              */
    122 
    123             // 1. The owner info.
    124             LockPatternUtils utils = new LockPatternUtils(getActivity());
    125             utils.setVisiblePatternEnabled(
    126                     utils.isVisiblePatternEnabled(UserHandle.USER_SYSTEM),
    127                     UserHandle.USER_SYSTEM);
    128             if (utils.isOwnerInfoEnabled(UserHandle.USER_SYSTEM)) {
    129                 utils.setOwnerInfo(utils.getOwnerInfo(UserHandle.USER_SYSTEM),
    130                                    UserHandle.USER_SYSTEM);
    131             }
    132             int value = Settings.System.getInt(getContext().getContentResolver(),
    133                                                Settings.System.TEXT_SHOW_PASSWORD,
    134                                                1);
    135             utils.setVisiblePasswordEnabled(value != 0, UserHandle.USER_SYSTEM);
    136 
    137             Intent intent = new Intent(getActivity(), Blank.class);
    138             intent.putExtras(getArguments());
    139             startActivity(intent);
    140 
    141             // 2. The system locale.
    142             try {
    143                 IBinder service = ServiceManager.getService("mount");
    144                 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
    145                 storageManager.setField("SystemLocale", Locale.getDefault().toLanguageTag());
    146             } catch (Exception e) {
    147                 Log.e(TAG, "Error storing locale for decryption UI", e);
    148             }
    149         }
    150     };
    151 
    152     private void establishFinalConfirmationState() {
    153         mFinalButton = (Button) mContentView.findViewById(R.id.execute_encrypt);
    154         mFinalButton.setOnClickListener(mFinalClickListener);
    155     }
    156 
    157     @Override
    158     public void onCreate(@Nullable Bundle savedInstanceState) {
    159         super.onCreate(savedInstanceState);
    160         getActivity().setTitle(R.string.crypt_keeper_confirm_title);
    161     }
    162 
    163     @Override
    164     public View onCreateView(LayoutInflater inflater, ViewGroup container,
    165             Bundle savedInstanceState) {
    166         mContentView = inflater.inflate(R.layout.crypt_keeper_confirm, null);
    167         establishFinalConfirmationState();
    168         return mContentView;
    169     }
    170 }
    171