Loading Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -276,6 +276,7 @@ LOCAL_SRC_FILES += \ core/java/com/android/internal/view/IInputMethodSession.aidl \ core/java/com/android/internal/view/IInputSessionCallback.aidl \ core/java/com/android/internal/widget/ILockSettings.aidl \ core/java/com/android/internal/widget/ILockSettingsObserver.aidl \ core/java/com/android/internal/widget/IRemoteViewsFactory.aidl \ core/java/com/android/internal/widget/IRemoteViewsAdapterConnection.aidl \ keystore/java/android/security/IKeyChainAliasCallback.aidl \ Loading core/java/com/android/internal/widget/ILockSettings.aidl +4 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.internal.widget; import com.android.internal.widget.ILockSettingsObserver; /** {@hide} */ interface ILockSettings { void setBoolean(in String key, in boolean value, in int userId); Loading @@ -32,4 +34,6 @@ interface ILockSettings { boolean havePattern(int userId); boolean havePassword(int userId); void removeUser(int userId); void registerObserver(in ILockSettingsObserver observer); void unregisterObserver(in ILockSettingsObserver observer); } core/java/com/android/internal/widget/ILockSettingsObserver.aidl 0 → 100644 +22 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.widget; /** {@hide} */ oneway interface ILockSettingsObserver { void onLockSettingChanged(in String key, in int userId); } core/java/com/android/internal/widget/LockPatternUtils.java +2 −2 Original line number Diff line number Diff line Loading @@ -199,8 +199,8 @@ public class LockPatternUtils { private ILockSettings getLockSettings() { if (mLockSettingsService == null) { mLockSettingsService = ILockSettings.Stub.asInterface( (IBinder) ServiceManager.getService("lock_settings")); mLockSettingsService = LockPatternUtilsCache.getInstance( ILockSettings.Stub.asInterface(ServiceManager.getService("lock_settings"))); } return mLockSettingsService; } Loading core/java/com/android/internal/widget/LockPatternUtilsCache.java 0 → 100644 +222 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package com.android.internal.widget; import android.os.IBinder; import android.os.RemoteException; import android.util.ArrayMap; /** * A decorator for {@link ILockSettings} that caches the key-value responses in memory. * * Specifically, the return values of {@link #getString(String, String, int)}, * {@link #getLong(String, long, int)} and {@link #getBoolean(String, boolean, int)} are cached. */ public class LockPatternUtilsCache implements ILockSettings { private static LockPatternUtilsCache sInstance; private final ILockSettings mService; /** Only access when holding {@code mCache} lock. */ private final ArrayMap<CacheKey, Object> mCache = new ArrayMap<>(); /** Only access when holding {@link #mCache} lock. */ private final CacheKey mCacheKey = new CacheKey(); public static synchronized LockPatternUtilsCache getInstance(ILockSettings service) { if (sInstance == null) { sInstance = new LockPatternUtilsCache(service); } return sInstance; } // ILockSettings private LockPatternUtilsCache(ILockSettings service) { mService = service; try { service.registerObserver(mObserver); } catch (RemoteException e) { // Not safe to do caching without the observer. System process has probably died // anyway, so crashing here is fine. throw new RuntimeException(e); } } public void setBoolean(String key, boolean value, int userId) throws RemoteException { invalidateCache(key, userId); mService.setBoolean(key, value, userId); putCache(key, userId, value); } public void setLong(String key, long value, int userId) throws RemoteException { invalidateCache(key, userId); mService.setLong(key, value, userId); putCache(key, userId, value); } public void setString(String key, String value, int userId) throws RemoteException { invalidateCache(key, userId); mService.setString(key, value, userId); putCache(key, userId, value); } public long getLong(String key, long defaultValue, int userId) throws RemoteException { Object value = peekCache(key, userId); if (value instanceof Long) { return (long) value; } long result = mService.getLong(key, defaultValue, userId); putCache(key, userId, result); return result; } public String getString(String key, String defaultValue, int userId) throws RemoteException { Object value = peekCache(key, userId); if (value instanceof String) { return (String) value; } String result = mService.getString(key, defaultValue, userId); putCache(key, userId, result); return result; } public boolean getBoolean(String key, boolean defaultValue, int userId) throws RemoteException { Object value = peekCache(key, userId); if (value instanceof Boolean) { return (boolean) value; } boolean result = mService.getBoolean(key, defaultValue, userId); putCache(key, userId, result); return result; } @Override public void setLockPattern(String pattern, int userId) throws RemoteException { mService.setLockPattern(pattern, userId); } @Override public boolean checkPattern(String pattern, int userId) throws RemoteException { return mService.checkPattern(pattern, userId); } @Override public void setLockPassword(String password, int userId) throws RemoteException { mService.setLockPassword(password, userId); } @Override public boolean checkPassword(String password, int userId) throws RemoteException { return mService.checkPassword(password, userId); } @Override public boolean checkVoldPassword(int userId) throws RemoteException { return mService.checkVoldPassword(userId); } @Override public boolean havePattern(int userId) throws RemoteException { return mService.havePattern(userId); } @Override public boolean havePassword(int userId) throws RemoteException { return mService.havePassword(userId); } @Override public void removeUser(int userId) throws RemoteException { mService.removeUser(userId); } @Override public void registerObserver(ILockSettingsObserver observer) throws RemoteException { mService.registerObserver(observer); } @Override public void unregisterObserver(ILockSettingsObserver observer) throws RemoteException { mService.unregisterObserver(observer); } @Override public IBinder asBinder() { return mService.asBinder(); } // Caching private Object peekCache(String key, int userId) { synchronized (mCache) { // Safe to reuse mCacheKey, because it is not stored in the map. return mCache.get(mCacheKey.set(key, userId)); } } private void putCache(String key, int userId, Object value) { synchronized (mCache) { // Create a new key, because this will be stored in the map. mCache.put(new CacheKey().set(key, userId), value); } } private void invalidateCache(String key, int userId) { synchronized (mCache) { // Safe to reuse mCacheKey, because it is not stored in the map. mCache.remove(mCacheKey.set(key, userId)); } } private final ILockSettingsObserver mObserver = new ILockSettingsObserver.Stub() { @Override public void onLockSettingChanged(String key, int userId) throws RemoteException { invalidateCache(key, userId); } }; private static final class CacheKey { String key; int userId; public CacheKey set(String key, int userId) { this.key = key; this.userId = userId; return this; } public CacheKey copy() { return new CacheKey().set(key, userId); } @Override public boolean equals(Object obj) { if (!(obj instanceof CacheKey)) return false; CacheKey o = (CacheKey) obj; return userId == o.userId && key.equals(o.key); } @Override public int hashCode() { return key.hashCode() ^ userId; } } } Loading
Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -276,6 +276,7 @@ LOCAL_SRC_FILES += \ core/java/com/android/internal/view/IInputMethodSession.aidl \ core/java/com/android/internal/view/IInputSessionCallback.aidl \ core/java/com/android/internal/widget/ILockSettings.aidl \ core/java/com/android/internal/widget/ILockSettingsObserver.aidl \ core/java/com/android/internal/widget/IRemoteViewsFactory.aidl \ core/java/com/android/internal/widget/IRemoteViewsAdapterConnection.aidl \ keystore/java/android/security/IKeyChainAliasCallback.aidl \ Loading
core/java/com/android/internal/widget/ILockSettings.aidl +4 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.internal.widget; import com.android.internal.widget.ILockSettingsObserver; /** {@hide} */ interface ILockSettings { void setBoolean(in String key, in boolean value, in int userId); Loading @@ -32,4 +34,6 @@ interface ILockSettings { boolean havePattern(int userId); boolean havePassword(int userId); void removeUser(int userId); void registerObserver(in ILockSettingsObserver observer); void unregisterObserver(in ILockSettingsObserver observer); }
core/java/com/android/internal/widget/ILockSettingsObserver.aidl 0 → 100644 +22 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.widget; /** {@hide} */ oneway interface ILockSettingsObserver { void onLockSettingChanged(in String key, in int userId); }
core/java/com/android/internal/widget/LockPatternUtils.java +2 −2 Original line number Diff line number Diff line Loading @@ -199,8 +199,8 @@ public class LockPatternUtils { private ILockSettings getLockSettings() { if (mLockSettingsService == null) { mLockSettingsService = ILockSettings.Stub.asInterface( (IBinder) ServiceManager.getService("lock_settings")); mLockSettingsService = LockPatternUtilsCache.getInstance( ILockSettings.Stub.asInterface(ServiceManager.getService("lock_settings"))); } return mLockSettingsService; } Loading
core/java/com/android/internal/widget/LockPatternUtilsCache.java 0 → 100644 +222 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ package com.android.internal.widget; import android.os.IBinder; import android.os.RemoteException; import android.util.ArrayMap; /** * A decorator for {@link ILockSettings} that caches the key-value responses in memory. * * Specifically, the return values of {@link #getString(String, String, int)}, * {@link #getLong(String, long, int)} and {@link #getBoolean(String, boolean, int)} are cached. */ public class LockPatternUtilsCache implements ILockSettings { private static LockPatternUtilsCache sInstance; private final ILockSettings mService; /** Only access when holding {@code mCache} lock. */ private final ArrayMap<CacheKey, Object> mCache = new ArrayMap<>(); /** Only access when holding {@link #mCache} lock. */ private final CacheKey mCacheKey = new CacheKey(); public static synchronized LockPatternUtilsCache getInstance(ILockSettings service) { if (sInstance == null) { sInstance = new LockPatternUtilsCache(service); } return sInstance; } // ILockSettings private LockPatternUtilsCache(ILockSettings service) { mService = service; try { service.registerObserver(mObserver); } catch (RemoteException e) { // Not safe to do caching without the observer. System process has probably died // anyway, so crashing here is fine. throw new RuntimeException(e); } } public void setBoolean(String key, boolean value, int userId) throws RemoteException { invalidateCache(key, userId); mService.setBoolean(key, value, userId); putCache(key, userId, value); } public void setLong(String key, long value, int userId) throws RemoteException { invalidateCache(key, userId); mService.setLong(key, value, userId); putCache(key, userId, value); } public void setString(String key, String value, int userId) throws RemoteException { invalidateCache(key, userId); mService.setString(key, value, userId); putCache(key, userId, value); } public long getLong(String key, long defaultValue, int userId) throws RemoteException { Object value = peekCache(key, userId); if (value instanceof Long) { return (long) value; } long result = mService.getLong(key, defaultValue, userId); putCache(key, userId, result); return result; } public String getString(String key, String defaultValue, int userId) throws RemoteException { Object value = peekCache(key, userId); if (value instanceof String) { return (String) value; } String result = mService.getString(key, defaultValue, userId); putCache(key, userId, result); return result; } public boolean getBoolean(String key, boolean defaultValue, int userId) throws RemoteException { Object value = peekCache(key, userId); if (value instanceof Boolean) { return (boolean) value; } boolean result = mService.getBoolean(key, defaultValue, userId); putCache(key, userId, result); return result; } @Override public void setLockPattern(String pattern, int userId) throws RemoteException { mService.setLockPattern(pattern, userId); } @Override public boolean checkPattern(String pattern, int userId) throws RemoteException { return mService.checkPattern(pattern, userId); } @Override public void setLockPassword(String password, int userId) throws RemoteException { mService.setLockPassword(password, userId); } @Override public boolean checkPassword(String password, int userId) throws RemoteException { return mService.checkPassword(password, userId); } @Override public boolean checkVoldPassword(int userId) throws RemoteException { return mService.checkVoldPassword(userId); } @Override public boolean havePattern(int userId) throws RemoteException { return mService.havePattern(userId); } @Override public boolean havePassword(int userId) throws RemoteException { return mService.havePassword(userId); } @Override public void removeUser(int userId) throws RemoteException { mService.removeUser(userId); } @Override public void registerObserver(ILockSettingsObserver observer) throws RemoteException { mService.registerObserver(observer); } @Override public void unregisterObserver(ILockSettingsObserver observer) throws RemoteException { mService.unregisterObserver(observer); } @Override public IBinder asBinder() { return mService.asBinder(); } // Caching private Object peekCache(String key, int userId) { synchronized (mCache) { // Safe to reuse mCacheKey, because it is not stored in the map. return mCache.get(mCacheKey.set(key, userId)); } } private void putCache(String key, int userId, Object value) { synchronized (mCache) { // Create a new key, because this will be stored in the map. mCache.put(new CacheKey().set(key, userId), value); } } private void invalidateCache(String key, int userId) { synchronized (mCache) { // Safe to reuse mCacheKey, because it is not stored in the map. mCache.remove(mCacheKey.set(key, userId)); } } private final ILockSettingsObserver mObserver = new ILockSettingsObserver.Stub() { @Override public void onLockSettingChanged(String key, int userId) throws RemoteException { invalidateCache(key, userId); } }; private static final class CacheKey { String key; int userId; public CacheKey set(String key, int userId) { this.key = key; this.userId = userId; return this; } public CacheKey copy() { return new CacheKey().set(key, userId); } @Override public boolean equals(Object obj) { if (!(obj instanceof CacheKey)) return false; CacheKey o = (CacheKey) obj; return userId == o.userId && key.equals(o.key); } @Override public int hashCode() { return key.hashCode() ^ userId; } } }