• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * 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, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 
17 package com.googlecode.eyesfree.braille.selfbraille;
18 
19 import android.os.Bundle;
20 import android.os.Parcel;
21 import android.os.Parcelable;
22 import android.view.View;
23 import android.view.accessibility.AccessibilityNodeInfo;
24 
25 /**
26  * Represents what should be shown on the braille display for a
27  * part of the accessibility node tree.
28  */
29 public class WriteData implements Parcelable {
30 
31     private static final String PROP_SELECTION_START = "selectionStart";
32     private static final String PROP_SELECTION_END = "selectionEnd";
33 
34     private AccessibilityNodeInfo mAccessibilityNodeInfo;
35     private CharSequence mText;
36     private Bundle mProperties = Bundle.EMPTY;
37 
38     /**
39      * Returns a new {@link WriteData} instance for the given {@code view}.
40      */
forView(View view)41     public static WriteData forView(View view) {
42         AccessibilityNodeInfo node = AccessibilityNodeInfo.obtain(view);
43         WriteData writeData = new WriteData();
44         writeData.mAccessibilityNodeInfo = node;
45         return writeData;
46     }
47 
getAccessibilityNodeInfo()48     public AccessibilityNodeInfo getAccessibilityNodeInfo() {
49         return mAccessibilityNodeInfo;
50     }
51 
52     /**
53      * Sets the text to be displayed when the accessibility node associated
54      * with this instance has focus.  If this method is not called (or
55      * {@code text} is {@code null}), this client relinquishes control over
56      * this node.
57      */
setText(CharSequence text)58     public WriteData setText(CharSequence text) {
59         mText = text;
60         return this;
61     }
62 
getText()63     public CharSequence getText() {
64         return mText;
65     }
66 
67     /**
68      * Sets the start position in the text of a text selection or cursor that
69      * should be marked on the display.  A negative value (the default) means
70      * no selection will be added.
71      */
setSelectionStart(int v)72     public WriteData setSelectionStart(int v) {
73         writableProperties().putInt(PROP_SELECTION_START, v);
74         return this;
75     }
76 
77     /**
78      * @see {@link #setSelectionStart}.
79      */
getSelectionStart()80     public int getSelectionStart() {
81         return mProperties.getInt(PROP_SELECTION_START, -1);
82     }
83 
84     /**
85      * Sets the end of the text selection to be marked on the display.  This
86      * value should only be non-negative if the selection start is
87      * non-negative.  If this value is <= the selection start, the selection
88      * is a cursor.  Otherwise, the selection covers the range from
89      * start(inclusive) to end (exclusive).
90      *
91      * @see {@link android.text.Selection}.
92      */
setSelectionEnd(int v)93     public WriteData setSelectionEnd(int v) {
94         writableProperties().putInt(PROP_SELECTION_END, v);
95         return this;
96     }
97 
98     /**
99      * @see {@link #setSelectionEnd}.
100      */
getSelectionEnd()101     public int getSelectionEnd() {
102         return mProperties.getInt(PROP_SELECTION_END, -1);
103     }
104 
writableProperties()105     private Bundle writableProperties() {
106         if (mProperties == Bundle.EMPTY) {
107             mProperties = new Bundle();
108         }
109         return mProperties;
110     }
111 
112     /**
113      * Checks constraints on the fields that must be satisfied before sending
114      * this instance to the self braille service.
115      * @throws IllegalStateException
116      */
validate()117     public void validate() throws IllegalStateException {
118         if (mAccessibilityNodeInfo == null) {
119             throw new IllegalStateException(
120                 "Accessibility node info can't be null");
121         }
122         int selectionStart = getSelectionStart();
123         int selectionEnd = getSelectionEnd();
124         if (mText == null) {
125             if (selectionStart > 0 || selectionEnd > 0) {
126                 throw new IllegalStateException(
127                     "Selection can't be set without text");
128             }
129         } else {
130             if (selectionStart < 0 && selectionEnd >= 0) {
131                 throw new IllegalStateException(
132                     "Selection end without start");
133             }
134             int textLength = mText.length();
135             if (selectionStart > textLength || selectionEnd > textLength) {
136                 throw new IllegalStateException("Selection out of bounds");
137             }
138         }
139     }
140 
141     // For Parcelable support.
142 
143     public static final Parcelable.Creator<WriteData> CREATOR =
144         new Parcelable.Creator<WriteData>() {
145             @Override
146             public WriteData createFromParcel(Parcel in) {
147                 return new WriteData(in);
148             }
149 
150             @Override
151             public WriteData[] newArray(int size) {
152                 return new WriteData[size];
153             }
154         };
155 
156     @Override
describeContents()157     public int describeContents() {
158         return 0;
159     }
160 
161     /**
162      * {@inheritDoc}
163      * <strong>Note:</strong> The {@link AccessibilityNodeInfo} will be
164      * recycled by this method, don't try to use this more than once.
165      */
166     @Override
writeToParcel(Parcel out, int flags)167     public void writeToParcel(Parcel out, int flags) {
168         mAccessibilityNodeInfo.writeToParcel(out, flags);
169         // The above call recycles the node, so make sure we don't use it
170         // anymore.
171         mAccessibilityNodeInfo = null;
172         out.writeString(mText.toString());
173         out.writeBundle(mProperties);
174     }
175 
WriteData()176     private WriteData() {
177     }
178 
WriteData(Parcel in)179     private WriteData(Parcel in) {
180         mAccessibilityNodeInfo =
181                 AccessibilityNodeInfo.CREATOR.createFromParcel(in);
182         mText = in.readString();
183         mProperties = in.readBundle();
184     }
185 }
186