152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani/*
252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * Copyright (C) 2012 The Android Open Source Project
352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani *
452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * Licensed under the Apache License, Version 2.0 (the "License");
552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * you may not use this file except in compliance with the License.
652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * You may obtain a copy of the License at
752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani *
852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani *      http://www.apache.org/licenses/LICENSE-2.0
952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani *
1052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * Unless required by applicable law or agreed to in writing, software
1152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * distributed under the License is distributed on an "AS IS" BASIS,
1252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * See the License for the specific language governing permissions and
1452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * limitations under the License.
1552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani */
1652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
177a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeypackage com.android.server;
1852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
19f0246a8a14d69680d1776620e75a485cf963e574Robin Leeimport android.content.BroadcastReceiver;
2052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport android.content.ContentResolver;
2152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport android.content.Context;
22f0246a8a14d69680d1776620e75a485cf963e574Robin Leeimport android.content.Intent;
23f0246a8a14d69680d1776620e75a485cf963e574Robin Leeimport android.content.IntentFilter;
24158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Millerimport android.content.pm.PackageManager;
25187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Millerimport android.content.pm.UserInfo;
26187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller
27261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roosimport static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE;
28187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Millerimport static android.content.Context.USER_SERVICE;
29158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Millerimport static android.Manifest.permission.READ_PROFILE;
30261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos
3152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport android.database.sqlite.SQLiteDatabase;
3252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport android.os.Binder;
33945490c12e32b1c13b9097c00702558260b2011fPaul Lawrenceimport android.os.IBinder;
34f0246a8a14d69680d1776620e75a485cf963e574Robin Leeimport android.os.Process;
3552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport android.os.RemoteException;
36945490c12e32b1c13b9097c00702558260b2011fPaul Lawrenceimport android.os.storage.IMountService;
37945490c12e32b1c13b9097c00702558260b2011fPaul Lawrenceimport android.os.ServiceManager;
38d1645f8d0f30709340eb6b6d6da5022bbab77024Amith Yamasaniimport android.os.SystemProperties;
39f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackbornimport android.os.UserHandle;
40187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Millerimport android.os.UserManager;
4152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport android.provider.Settings;
4252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport android.provider.Settings.Secure;
43187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Millerimport android.provider.Settings.SettingNotFoundException;
44de1af08dd3a073f007ae4b8a114352cae3775028Jim Millerimport android.security.KeyStore;
4552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport android.text.TextUtils;
4652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport android.util.Slog;
4752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
487a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport com.android.internal.widget.ILockSettings;
497a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkeyimport com.android.internal.widget.LockPatternUtils;
507a96c39c510923ef73bbb06ab20109f0168b8eb1Jeff Sharkey
514f7884542ce8fba5bfed01ed834a32e6d3e2dea5Adrian Roosimport java.util.ArrayList;
5252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasaniimport java.util.Arrays;
53187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Millerimport java.util.List;
5452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
5552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani/**
5652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * Keeps the lock pattern/password data and related settings for each user.
5752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * Used by LockPatternUtils. Needs to be a service because Settings app also needs
5852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * to be able to save lockscreen information for secondary users.
5952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani * @hide
6052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani */
6152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasanipublic class LockSettingsService extends ILockSettings.Stub {
6252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
63261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos    private static final String PERMISSION = ACCESS_KEYGUARD_SECURE_STORAGE;
644f7884542ce8fba5bfed01ed834a32e6d3e2dea5Adrian Roos
65261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos    private static final String TAG = "LockSettingsService";
6652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
67261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos    private final Context mContext;
6852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
69261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos    private final LockSettingsStorage mStorage;
7052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
71de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller    private LockPatternUtils mLockPatternUtils;
72945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence    private boolean mFirstCallToVold;
7352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
7452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    public LockSettingsService(Context context) {
7552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        mContext = context;
7652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        // Open the database
77de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller
78de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller        mLockPatternUtils = new LockPatternUtils(context);
79945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        mFirstCallToVold = true;
80f0246a8a14d69680d1776620e75a485cf963e574Robin Lee
81f0246a8a14d69680d1776620e75a485cf963e574Robin Lee        IntentFilter filter = new IntentFilter();
82f0246a8a14d69680d1776620e75a485cf963e574Robin Lee        filter.addAction(Intent.ACTION_USER_ADDED);
833dcae68501a1fc1c433d12a9d55a31c7eaab016cAdrian Roos        filter.addAction(Intent.ACTION_USER_STARTING);
84f0246a8a14d69680d1776620e75a485cf963e574Robin Lee        mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
85261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos
86261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        mStorage = new LockSettingsStorage(context, new LockSettingsStorage.Callback() {
87261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos            @Override
88261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos            public void initialize(SQLiteDatabase db) {
89261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos                // Get the lockscreen default from a system property, if available
90261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos                boolean lockScreenDisable = SystemProperties.getBoolean(
91261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos                        "ro.lockscreen.disable.default", false);
92261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos                if (lockScreenDisable) {
93261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos                    mStorage.writeKeyValue(db, LockPatternUtils.DISABLE_LOCKSCREEN_KEY, "1", 0);
94261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos                }
95261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos            }
96261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        });
9752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    }
9852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
99f0246a8a14d69680d1776620e75a485cf963e574Robin Lee    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
100f0246a8a14d69680d1776620e75a485cf963e574Robin Lee        @Override
101f0246a8a14d69680d1776620e75a485cf963e574Robin Lee        public void onReceive(Context context, Intent intent) {
1021096cf8664963a136a325b2bc511c8f381b9ba77Robin Lee            if (Intent.ACTION_USER_ADDED.equals(intent.getAction())) {
103f0246a8a14d69680d1776620e75a485cf963e574Robin Lee                final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
10449d810cb632bd4c334ebfd3932658fa6973bcbefRobin Lee                final int userSysUid = UserHandle.getUid(userHandle, Process.SYSTEM_UID);
10549d810cb632bd4c334ebfd3932658fa6973bcbefRobin Lee                final KeyStore ks = KeyStore.getInstance();
10649d810cb632bd4c334ebfd3932658fa6973bcbefRobin Lee
10749d810cb632bd4c334ebfd3932658fa6973bcbefRobin Lee                // Clear up keystore in case anything was left behind by previous users
10849d810cb632bd4c334ebfd3932658fa6973bcbefRobin Lee                ks.resetUid(userSysUid);
10949d810cb632bd4c334ebfd3932658fa6973bcbefRobin Lee
11049d810cb632bd4c334ebfd3932658fa6973bcbefRobin Lee                // If this user has a parent, sync with its keystore password
111f0246a8a14d69680d1776620e75a485cf963e574Robin Lee                final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
112f0246a8a14d69680d1776620e75a485cf963e574Robin Lee                final UserInfo parentInfo = um.getProfileParent(userHandle);
113f0246a8a14d69680d1776620e75a485cf963e574Robin Lee                if (parentInfo != null) {
11449d810cb632bd4c334ebfd3932658fa6973bcbefRobin Lee                    final int parentSysUid = UserHandle.getUid(parentInfo.id, Process.SYSTEM_UID);
11549d810cb632bd4c334ebfd3932658fa6973bcbefRobin Lee                    ks.syncUid(parentSysUid, userSysUid);
116f0246a8a14d69680d1776620e75a485cf963e574Robin Lee                }
1173dcae68501a1fc1c433d12a9d55a31c7eaab016cAdrian Roos            } else if (Intent.ACTION_USER_STARTING.equals(intent.getAction())) {
1183dcae68501a1fc1c433d12a9d55a31c7eaab016cAdrian Roos                final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
1193dcae68501a1fc1c433d12a9d55a31c7eaab016cAdrian Roos                mStorage.prefetchUser(userHandle);
120f0246a8a14d69680d1776620e75a485cf963e574Robin Lee            }
121f0246a8a14d69680d1776620e75a485cf963e574Robin Lee        }
122f0246a8a14d69680d1776620e75a485cf963e574Robin Lee    };
123f0246a8a14d69680d1776620e75a485cf963e574Robin Lee
12452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    public void systemReady() {
12552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        migrateOldData();
1263dcae68501a1fc1c433d12a9d55a31c7eaab016cAdrian Roos        mStorage.prefetchUser(UserHandle.USER_OWNER);
12752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    }
12852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
12952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    private void migrateOldData() {
13052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        try {
131187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller            // These Settings moved before multi-user was enabled, so we only have to do it for the
132187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller            // root user.
133187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller            if (getString("migrated", null, 0) == null) {
134187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller                final ContentResolver cr = mContext.getContentResolver();
135187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller                for (String validSetting : VALID_SETTINGS) {
136187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller                    String value = Settings.Secure.getString(cr, validSetting);
137187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller                    if (value != null) {
138187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller                        setString(validSetting, value, 0);
139187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller                    }
140187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller                }
141187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller                // No need to move the password / pattern files. They're already in the right place.
142187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller                setString("migrated", "true", 0);
143187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller                Slog.i(TAG, "Migrated lock settings to new location");
14452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani            }
14552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
146187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller            // These Settings changed after multi-user was enabled, hence need to be moved per user.
147187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller            if (getString("migrated_user_specific", null, 0) == null) {
148187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller                final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
149187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller                final ContentResolver cr = mContext.getContentResolver();
150187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller                List<UserInfo> users = um.getUsers();
151187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller                for (int user = 0; user < users.size(); user++) {
1522d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller                    // Migrate owner info
1532d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller                    final int userId = users.get(user).id;
1542d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller                    final String OWNER_INFO = Secure.LOCK_SCREEN_OWNER_INFO;
1552d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller                    String ownerInfo = Settings.Secure.getStringForUser(cr, OWNER_INFO, userId);
1562d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller                    if (ownerInfo != null) {
1572d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller                        setString(OWNER_INFO, ownerInfo, userId);
1582d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller                        Settings.Secure.putStringForUser(cr, ownerInfo, "", userId);
1592d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller                    }
160187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller
1612d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller                    // Migrate owner info enabled.  Note there was a bug where older platforms only
1622d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller                    // stored this value if the checkbox was toggled at least once. The code detects
1632d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller                    // this case by handling the exception.
1642d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller                    final String OWNER_INFO_ENABLED = Secure.LOCK_SCREEN_OWNER_INFO_ENABLED;
1652d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller                    boolean enabled;
1662d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller                    try {
1672d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller                        int ivalue = Settings.Secure.getIntForUser(cr, OWNER_INFO_ENABLED, userId);
1682d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller                        enabled = ivalue != 0;
1692d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller                        setLong(OWNER_INFO_ENABLED, enabled ? 1 : 0, userId);
1702d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller                    } catch (SettingNotFoundException e) {
1712d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller                        // Setting was never stored. Store it if the string is not empty.
1722d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller                        if (!TextUtils.isEmpty(ownerInfo)) {
1732d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller                            setLong(OWNER_INFO_ENABLED, 1, userId);
174187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller                        }
175187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller                    }
1762d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller                    Settings.Secure.putIntForUser(cr, OWNER_INFO_ENABLED, 0, userId);
17752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani                }
178187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller                // No need to move the password / pattern files. They're already in the right place.
179187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller                setString("migrated_user_specific", "true", 0);
180187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller                Slog.i(TAG, "Migrated per-user lock settings to new location");
18152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani            }
18252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        } catch (RemoteException re) {
183187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller            Slog.e(TAG, "Unable to migrate old data", re);
18452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        }
18552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    }
18652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
1875ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller    private final void checkWritePermission(int userId) {
188505329b21b743c6e74e0d1b14bea78a22f7b4145Jim Miller        mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsWrite");
18952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    }
19052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
1915ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller    private final void checkPasswordReadPermission(int userId) {
192505329b21b743c6e74e0d1b14bea78a22f7b4145Jim Miller        mContext.enforceCallingOrSelfPermission(PERMISSION, "LockSettingsRead");
19352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    }
19452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
195158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller    private final void checkReadPermission(String requestedKey, int userId) {
19652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        final int callingUid = Binder.getCallingUid();
197158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller        for (int i = 0; i < READ_PROFILE_PROTECTED_SETTINGS.length; i++) {
198158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller            String key = READ_PROFILE_PROTECTED_SETTINGS[i];
199158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller            if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(READ_PROFILE)
200158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller                    != PackageManager.PERMISSION_GRANTED) {
201158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller                throw new SecurityException("uid=" + callingUid
202158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller                        + " needs permission " + READ_PROFILE + " to read "
203158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller                        + requestedKey + " for user " + userId);
204158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller            }
20552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        }
20652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    }
20752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
20852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    @Override
20952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    public void setBoolean(String key, boolean value, int userId) throws RemoteException {
21052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        checkWritePermission(userId);
211261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        setStringUnchecked(key, userId, value ? "1" : "0");
21252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    }
21352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
21452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    @Override
21552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    public void setLong(String key, long value, int userId) throws RemoteException {
21652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        checkWritePermission(userId);
217261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        setStringUnchecked(key, userId, Long.toString(value));
21852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    }
21952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
22052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    @Override
22152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    public void setString(String key, String value, int userId) throws RemoteException {
22252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        checkWritePermission(userId);
223261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        setStringUnchecked(key, userId, value);
224261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos    }
22552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
226261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos    private void setStringUnchecked(String key, int userId, String value) {
227261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        mStorage.writeKeyValue(key, value, userId);
22852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    }
22952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
23052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    @Override
23152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    public boolean getBoolean(String key, boolean defaultValue, int userId) throws RemoteException {
232158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller        checkReadPermission(key, userId);
23352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
234261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        String value = mStorage.readKeyValue(key, null, userId);
23552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        return TextUtils.isEmpty(value) ?
23652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani                defaultValue : (value.equals("1") || value.equals("true"));
23752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    }
23852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
23952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    @Override
24052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    public long getLong(String key, long defaultValue, int userId) throws RemoteException {
241158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller        checkReadPermission(key, userId);
24252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
243261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        String value = mStorage.readKeyValue(key, null, userId);
24452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        return TextUtils.isEmpty(value) ? defaultValue : Long.parseLong(value);
24552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    }
24652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
24752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    @Override
24852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    public String getString(String key, String defaultValue, int userId) throws RemoteException {
249158fe19ff88e577ceda4b92c26d3dfb8dfbed117Jim Miller        checkReadPermission(key, userId);
25052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
251261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        return mStorage.readKeyValue(key, defaultValue, userId);
25252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    }
25352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
2544f7884542ce8fba5bfed01ed834a32e6d3e2dea5Adrian Roos    @Override
25552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    public boolean havePassword(int userId) throws RemoteException {
25652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        // Do we need a permissions check here?
25752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
258261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        return mStorage.hasPassword(userId);
25952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    }
26052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
26152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    @Override
26252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    public boolean havePattern(int userId) throws RemoteException {
26352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        // Do we need a permissions check here?
26452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
265261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        return mStorage.hasPattern(userId);
26652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    }
26752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
268f0246a8a14d69680d1776620e75a485cf963e574Robin Lee    private void maybeUpdateKeystore(String password, int userHandle) {
269f0246a8a14d69680d1776620e75a485cf963e574Robin Lee        final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
270f0246a8a14d69680d1776620e75a485cf963e574Robin Lee        final KeyStore ks = KeyStore.getInstance();
271f0246a8a14d69680d1776620e75a485cf963e574Robin Lee
272f0246a8a14d69680d1776620e75a485cf963e574Robin Lee        final List<UserInfo> profiles = um.getProfiles(userHandle);
273f0246a8a14d69680d1776620e75a485cf963e574Robin Lee        boolean shouldReset = TextUtils.isEmpty(password);
274f0246a8a14d69680d1776620e75a485cf963e574Robin Lee
275f0246a8a14d69680d1776620e75a485cf963e574Robin Lee        // For historical reasons, don't wipe a non-empty keystore if we have a single user with a
276f0246a8a14d69680d1776620e75a485cf963e574Robin Lee        // single profile.
277f0246a8a14d69680d1776620e75a485cf963e574Robin Lee        if (userHandle == UserHandle.USER_OWNER && profiles.size() == 1) {
278f0246a8a14d69680d1776620e75a485cf963e574Robin Lee            if (!ks.isEmpty()) {
279f0246a8a14d69680d1776620e75a485cf963e574Robin Lee                shouldReset = false;
280f0246a8a14d69680d1776620e75a485cf963e574Robin Lee            }
281f0246a8a14d69680d1776620e75a485cf963e574Robin Lee        }
282f0246a8a14d69680d1776620e75a485cf963e574Robin Lee
283f0246a8a14d69680d1776620e75a485cf963e574Robin Lee        for (UserInfo pi : profiles) {
284f0246a8a14d69680d1776620e75a485cf963e574Robin Lee            final int profileUid = UserHandle.getUid(pi.id, Process.SYSTEM_UID);
285f0246a8a14d69680d1776620e75a485cf963e574Robin Lee            if (shouldReset) {
286f0246a8a14d69680d1776620e75a485cf963e574Robin Lee                ks.resetUid(profileUid);
287de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller            } else {
288f0246a8a14d69680d1776620e75a485cf963e574Robin Lee                ks.passwordUid(password, profileUid);
289de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller            }
290de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller        }
291de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller    }
292de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller
29352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    @Override
294de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller    public void setLockPattern(String pattern, int userId) throws RemoteException {
29552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        checkWritePermission(userId);
29652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
297de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller        maybeUpdateKeystore(pattern, userId);
298de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller
299de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller        final byte[] hash = LockPatternUtils.patternToHash(
300de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller                LockPatternUtils.stringToPattern(pattern));
301261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        mStorage.writePatternHash(hash, userId);
30252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    }
30352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
30452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    @Override
305de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller    public void setLockPassword(String password, int userId) throws RemoteException {
306de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller        checkWritePermission(userId);
307de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller
308de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller        maybeUpdateKeystore(password, userId);
309de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller
310261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        mStorage.writePasswordHash(mLockPatternUtils.passwordToHash(password, userId), userId);
311de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller    }
312de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller
313de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller    @Override
314de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller    public boolean checkPattern(String pattern, int userId) throws RemoteException {
31552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        checkPasswordReadPermission(userId);
316261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        byte[] hash = LockPatternUtils.patternToHash(LockPatternUtils.stringToPattern(pattern));
317261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        byte[] storedHash = mStorage.readPatternHash(userId);
318261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos
319261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        if (storedHash == null) {
320261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos            return true;
32152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        }
322261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos
323261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        boolean matched = Arrays.equals(hash, storedHash);
324261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        if (matched && !TextUtils.isEmpty(pattern)) {
325261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos            maybeUpdateKeystore(pattern, userId);
326261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        }
327261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        return matched;
32852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    }
32952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
33052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    @Override
331de1af08dd3a073f007ae4b8a114352cae3775028Jim Miller    public boolean checkPassword(String password, int userId) throws RemoteException {
33252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        checkPasswordReadPermission(userId);
33352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
334261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        byte[] hash = mLockPatternUtils.passwordToHash(password, userId);
335261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        byte[] storedHash = mStorage.readPasswordHash(userId);
336261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos
337261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        if (storedHash == null) {
338261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos            return true;
339261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        }
340261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos
341261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        boolean matched = Arrays.equals(hash, storedHash);
342261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        if (matched && !TextUtils.isEmpty(password)) {
343261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos            maybeUpdateKeystore(password, userId);
34452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        }
345261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        return matched;
34652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    }
34752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
34852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    @Override
349261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos    public boolean checkVoldPassword(int userId) throws RemoteException {
350945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        if (!mFirstCallToVold) {
351945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence            return false;
352945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        }
353945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        mFirstCallToVold = false;
354945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence
355945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        checkPasswordReadPermission(userId);
356945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence
357945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        // There's no guarantee that this will safely connect, but if it fails
358945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        // we will simply show the lock screen when we shouldn't, so relatively
359945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        // benign. There is an outside chance something nasty would happen if
360945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        // this service restarted before vold stales out the password in this
361945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        // case. The nastiness is limited to not showing the lock screen when
362945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        // we should, within the first minute of decrypting the phone if this
363945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        // service can't connect to vold, it restarts, and then the new instance
364945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        // does successfully connect.
365945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        final IMountService service = getMountService();
366945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        String password = service.getPassword();
367945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        service.clearPassword();
368945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        if (password == null) {
369945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence            return false;
370945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        }
371945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence
372945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        try {
373945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence            if (mLockPatternUtils.isLockPatternEnabled()) {
374945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence                if (checkPattern(password, userId)) {
375945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence                    return true;
376945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence                }
377945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence            }
378945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        } catch (Exception e) {
379945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        }
380945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence
381945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        try {
382945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence            if (mLockPatternUtils.isLockPasswordEnabled()) {
383945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence                if (checkPassword(password, userId)) {
384945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence                    return true;
385945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence                }
386945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence            }
387945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        } catch (Exception e) {
388945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        }
389945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence
390945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        return false;
391945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence    }
392945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence
393945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence    @Override
39452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    public void removeUser(int userId) {
39552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        checkWritePermission(userId);
39652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
397261d5ab8f4c3fdd34163468fd48ab07f7ad13d3cAdrian Roos        mStorage.removeUser(userId);
39849d810cb632bd4c334ebfd3932658fa6973bcbefRobin Lee
39949d810cb632bd4c334ebfd3932658fa6973bcbefRobin Lee        final KeyStore ks = KeyStore.getInstance();
40049d810cb632bd4c334ebfd3932658fa6973bcbefRobin Lee        final int userUid = UserHandle.getUid(userId, Process.SYSTEM_UID);
40149d810cb632bd4c334ebfd3932658fa6973bcbefRobin Lee        ks.resetUid(userUid);
40252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    }
40352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani
40452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani    private static final String[] VALID_SETTINGS = new String[] {
40552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        LockPatternUtils.LOCKOUT_PERMANENT_KEY,
40652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        LockPatternUtils.LOCKOUT_ATTEMPT_DEADLINE,
40752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        LockPatternUtils.PATTERN_EVER_CHOSEN_KEY,
40852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        LockPatternUtils.PASSWORD_TYPE_KEY,
40952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        LockPatternUtils.PASSWORD_TYPE_ALTERNATE_KEY,
41052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        LockPatternUtils.LOCK_PASSWORD_SALT_KEY,
41152c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        LockPatternUtils.DISABLE_LOCKSCREEN_KEY,
41252c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        LockPatternUtils.LOCKSCREEN_OPTIONS,
41352c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK,
41452c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        LockPatternUtils.BIOMETRIC_WEAK_EVER_CHOSEN_KEY,
41552c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        LockPatternUtils.LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS,
41652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        LockPatternUtils.PASSWORD_HISTORY_KEY,
41752c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        Secure.LOCK_PATTERN_ENABLED,
41852c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        Secure.LOCK_BIOMETRIC_WEAK_FLAGS,
41952c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        Secure.LOCK_PATTERN_VISIBLE,
42052c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani        Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED
421187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller    };
422187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller
4232d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller    // These are protected with a read permission
4242d8ecf9df0ba4f503a09e87f91d12433f29faf52Jim Miller    private static final String[] READ_PROFILE_PROTECTED_SETTINGS = new String[] {
425187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller        Secure.LOCK_SCREEN_OWNER_INFO_ENABLED,
426187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller        Secure.LOCK_SCREEN_OWNER_INFO
427187ec581c66fec49a5ee7db8edec6d9eb0e209fcJim Miller    };
428945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence
429945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence    private IMountService getMountService() {
430945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        final IBinder service = ServiceManager.getService("mount");
431945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        if (service != null) {
432945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence            return IMountService.Stub.asInterface(service);
433945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        }
434945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence        return null;
435945490c12e32b1c13b9097c00702558260b2011fPaul Lawrence    }
43652c489cd63cca0361f374f7cb392018fabfa8bccAmith Yamasani}
437