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