Home | History | Annotate | Download | only in settings
      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.content.Context;
     20 import android.content.res.TypedArray;
     21 import android.os.Parcel;
     22 import android.os.Parcelable;
     23 import android.preference.DialogPreference;
     24 import android.provider.Settings;
     25 import android.util.AttributeSet;
     26 import android.view.View;
     27 import android.view.accessibility.AccessibilityEvent;
     28 import android.view.accessibility.AccessibilityManager;
     29 
     30 /**
     31  * Preference for enabling accessibility script injection. It displays a warning
     32  * dialog before enabling the preference.
     33  */
     34 public class AccessibilityEnableScriptInjectionPreference extends DialogPreference {
     35 
     36     private boolean mInjectionAllowed;
     37     private boolean mSendClickAccessibilityEvent;
     38 
     39     public AccessibilityEnableScriptInjectionPreference(Context context, AttributeSet attrs) {
     40         super(context, attrs);
     41         updateSummary();
     42     }
     43 
     44     public void setInjectionAllowed(boolean injectionAllowed) {
     45         if (mInjectionAllowed != injectionAllowed) {
     46             mInjectionAllowed = injectionAllowed;
     47             persistBoolean(injectionAllowed);
     48             updateSummary();
     49         }
     50     }
     51 
     52     public boolean isInjectionAllowed() {
     53         return mInjectionAllowed;
     54     }
     55 
     56     @Override
     57     protected void onBindView(View view) {
     58         super.onBindView(view);
     59         View summaryView = view.findViewById(com.android.internal.R.id.summary);
     60         sendAccessibilityEvent(summaryView);
     61     }
     62 
     63     private void sendAccessibilityEvent(View view) {
     64         // Since the view is still not attached we create, populate,
     65         // and send the event directly since we do not know when it
     66         // will be attached and posting commands is not as clean.
     67         AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(getContext());
     68         if (mSendClickAccessibilityEvent && accessibilityManager.isEnabled()) {
     69             AccessibilityEvent event = AccessibilityEvent.obtain();
     70             event.setEventType(AccessibilityEvent.TYPE_VIEW_CLICKED);
     71             view.onInitializeAccessibilityEvent(event);
     72             view.dispatchPopulateAccessibilityEvent(event);
     73             accessibilityManager.sendAccessibilityEvent(event);
     74         }
     75         mSendClickAccessibilityEvent = false;
     76     }
     77 
     78     @Override
     79     protected void onClick() {
     80         if (isInjectionAllowed()) {
     81             setInjectionAllowed(false);
     82             // Update the system setting only upon user action.
     83             setSystemSetting(false);
     84             mSendClickAccessibilityEvent = true;
     85         } else {
     86             super.onClick();
     87             mSendClickAccessibilityEvent = false;
     88         }
     89     }
     90 
     91     @Override
     92     protected Object onGetDefaultValue(TypedArray a, int index) {
     93         return a.getBoolean(index, false);
     94     }
     95 
     96     @Override
     97     protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
     98         setInjectionAllowed(restoreValue
     99                 ? getPersistedBoolean(mInjectionAllowed)
    100                 : (Boolean) defaultValue);
    101     }
    102 
    103     @Override
    104     protected void onDialogClosed(boolean result) {
    105         setInjectionAllowed(result);
    106         if (result) {
    107             // Update the system setting only upon user action.
    108             setSystemSetting(true);
    109         }
    110     }
    111 
    112     @Override
    113     protected Parcelable onSaveInstanceState() {
    114         Parcelable superState = super.onSaveInstanceState();
    115         if (isPersistent()) {
    116             return superState;
    117         }
    118         SavedState myState = new SavedState(superState);
    119         myState.mInjectionAllowed = mInjectionAllowed;
    120         return myState;
    121     }
    122 
    123     @Override
    124     protected void onRestoreInstanceState(Parcelable state) {
    125         if (state == null || !state.getClass().equals(SavedState.class)) {
    126             super.onRestoreInstanceState(state);
    127             return;
    128         }
    129         SavedState myState = (SavedState) state;
    130         super.onRestoreInstanceState(myState.getSuperState());
    131         setInjectionAllowed(myState.mInjectionAllowed);
    132     }
    133 
    134     private void updateSummary() {
    135         setSummary(mInjectionAllowed
    136                 ? getContext().getString(R.string.accessibility_script_injection_allowed)
    137                 : getContext().getString(R.string.accessibility_script_injection_disallowed));
    138     }
    139 
    140     private void setSystemSetting(boolean enabled) {
    141         Settings.Secure.putInt(getContext().getContentResolver(),
    142                 Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, enabled ? 1 : 0);
    143     }
    144 
    145     private static class SavedState extends BaseSavedState {
    146         private boolean mInjectionAllowed;
    147 
    148         public SavedState(Parcel source) {
    149             super(source);
    150             mInjectionAllowed = (source.readInt() == 1);
    151         }
    152 
    153         @Override
    154         public void writeToParcel(Parcel parcel, int flags) {
    155             super.writeToParcel(parcel, flags);
    156             parcel.writeInt(mInjectionAllowed ? 1 : 0);
    157         }
    158 
    159         public SavedState(Parcelable superState) {
    160             super(superState);
    161         }
    162 
    163         @SuppressWarnings("all")
    164         public static final Parcelable.Creator<SavedState> CREATOR =
    165                 new Parcelable.Creator<SavedState>() {
    166             public SavedState createFromParcel(Parcel in) {
    167                 return new SavedState(in);
    168             }
    169 
    170             public SavedState[] newArray(int size) {
    171                 return new SavedState[size];
    172             }
    173         };
    174     }
    175 }
    176