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