• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.app.settings.SettingsEnums;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.os.Bundle;
26 import android.os.Handler;
27 import android.os.IBinder;
28 import android.os.ServiceManager;
29 import android.os.UserHandle;
30 import android.os.storage.IStorageManager;
31 import android.provider.Settings;
32 import android.util.Log;
33 import android.view.LayoutInflater;
34 import android.view.View;
35 import android.view.ViewGroup;
36 import android.widget.Button;
37 
38 import com.android.internal.widget.LockPatternUtils;
39 import com.android.settings.core.InstrumentedFragment;
40 
41 import java.util.Arrays;
42 import java.util.Locale;
43 
44 public class CryptKeeperConfirm extends InstrumentedFragment {
45 
46     private static final String TAG = "CryptKeeperConfirm";
47 
48     @Override
getMetricsCategory()49     public int getMetricsCategory() {
50         return SettingsEnums.CRYPT_KEEPER_CONFIRM;
51     }
52 
53     public static class Blank extends Activity {
54         private Handler mHandler = new Handler();
55 
56         @Override
onCreate(Bundle savedInstanceState)57         public void onCreate(Bundle savedInstanceState) {
58             super.onCreate(savedInstanceState);
59 
60             setContentView(R.layout.crypt_keeper_blank);
61 
62             if (Utils.isMonkeyRunning()) {
63                 finish();
64             }
65 
66             StatusBarManager sbm = (StatusBarManager) getSystemService(Context.STATUS_BAR_SERVICE);
67             sbm.disable(StatusBarManager.DISABLE_EXPAND
68                     | StatusBarManager.DISABLE_NOTIFICATION_ICONS
69                     | StatusBarManager.DISABLE_NOTIFICATION_ALERTS
70                     | StatusBarManager.DISABLE_SYSTEM_INFO
71                     | StatusBarManager.DISABLE_HOME
72                     | StatusBarManager.DISABLE_SEARCH
73                     | StatusBarManager.DISABLE_RECENT
74                     | StatusBarManager.DISABLE_BACK);
75 
76             // Post a delayed message in 700 milliseconds to enable encryption.
77             // NOTE: The animation on this activity is set for 500 milliseconds
78             // I am giving it a little extra time to complete.
79             mHandler.postDelayed(new Runnable() {
80                 public void run() {
81                     IBinder service = ServiceManager.getService("mount");
82                     if (service == null) {
83                         Log.e("CryptKeeper", "Failed to find the mount service");
84                         finish();
85                         return;
86                     }
87 
88                     IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
89                     try {
90                         Bundle args = getIntent().getExtras();
91                         // TODO(b/120484642): Update vold to accept a password as a byte array
92                         byte[] passwordBytes = args.getByteArray("password");
93                         String password = passwordBytes != null ? new String(passwordBytes) : null;
94                         Arrays.fill(passwordBytes, (byte) 0);
95                         storageManager.encryptStorage(args.getInt("type", -1),
96                                 password);
97                     } catch (Exception e) {
98                         Log.e("CryptKeeper", "Error while encrypting...", e);
99                     }
100                 }
101             }, 700);
102         }
103     }
104 
105     private View mContentView;
106     private Button mFinalButton;
107     private Button.OnClickListener mFinalClickListener = new Button.OnClickListener() {
108 
109         public void onClick(View v) {
110             if (Utils.isMonkeyRunning()) {
111                 return;
112             }
113 
114             /* WARNING - nasty hack!
115                Settings for the lock screen are not available to the crypto
116                screen (CryptKeeper) at boot. We duplicate the ones that
117                CryptKeeper needs to the crypto key/value store when they are
118                modified (see LockPatternUtils).
119                However, prior to encryption, the crypto key/value store is not
120                persisted across reboots, thus modified settings are lost to
121                CryptKeeper.
122                In order to make sure CryptKeeper had the correct settings after
123                first encrypting, we thus need to rewrite them, which ensures the
124                crypto key/value store is up to date. On encryption, this store
125                is then persisted, and the settings will be there on future
126                reboots.
127              */
128 
129             // 1. The owner info.
130             LockPatternUtils utils = new LockPatternUtils(getActivity());
131             utils.setVisiblePatternEnabled(
132                     utils.isVisiblePatternEnabled(UserHandle.USER_SYSTEM),
133                     UserHandle.USER_SYSTEM);
134             if (utils.isOwnerInfoEnabled(UserHandle.USER_SYSTEM)) {
135                 utils.setOwnerInfo(utils.getOwnerInfo(UserHandle.USER_SYSTEM),
136                                    UserHandle.USER_SYSTEM);
137             }
138             int value = Settings.System.getInt(getContext().getContentResolver(),
139                                                Settings.System.TEXT_SHOW_PASSWORD,
140                                                1);
141             utils.setVisiblePasswordEnabled(value != 0, UserHandle.USER_SYSTEM);
142 
143             Intent intent = new Intent(getActivity(), Blank.class);
144             intent.putExtras(getArguments());
145             startActivity(intent);
146 
147             // 2. The system locale.
148             try {
149                 IBinder service = ServiceManager.getService("mount");
150                 IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
151                 storageManager.setField("SystemLocale", Locale.getDefault().toLanguageTag());
152             } catch (Exception e) {
153                 Log.e(TAG, "Error storing locale for decryption UI", e);
154             }
155         }
156     };
157 
establishFinalConfirmationState()158     private void establishFinalConfirmationState() {
159         mFinalButton = (Button) mContentView.findViewById(R.id.execute_encrypt);
160         mFinalButton.setOnClickListener(mFinalClickListener);
161     }
162 
163     @Override
onCreate(@ullable Bundle savedInstanceState)164     public void onCreate(@Nullable Bundle savedInstanceState) {
165         super.onCreate(savedInstanceState);
166         getActivity().setTitle(R.string.crypt_keeper_confirm_title);
167     }
168 
169     @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)170     public View onCreateView(LayoutInflater inflater, ViewGroup container,
171             Bundle savedInstanceState) {
172         mContentView = inflater.inflate(R.layout.crypt_keeper_confirm, null);
173         establishFinalConfirmationState();
174         return mContentView;
175     }
176 }
177